blob: 4d296d46b73abdfc8fe422bc50d744eda7b9cd2c [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854
Guy Benyei11169dd2012-12-18 14:30:41 +00001855private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1858 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1860 void AddStmt(const Stmt *S);
1861 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865};
1866} // end anonyous namespace
1867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 // 'S' should always be non-null, since it comes from the
1870 // statement we are visiting.
1871 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1872}
1873
1874void
1875EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1876 if (Qualifier)
1877 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1878}
1879
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 if (S)
1882 WL.push_back(StmtVisit(S, Parent));
1883}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (D)
1886 WL.push_back(DeclVisit(D, Parent, isFirst));
1887}
1888void EnqueueVisitor::
1889 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1890 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(MemberRefVisit(D, L, Parent));
1896}
1897void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1898 if (TI)
1899 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1900 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 AddStmt(*Child);
1905 }
1906 if (size == WL.size())
1907 return;
1908 // Now reverse the entries we just added. This will match the DFS
1909 // ordering performed by the worklist.
1910 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1911 std::reverse(I, E);
1912}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001913namespace {
1914class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1915 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001916 /// \brief Process clauses with list of variables.
1917 template <typename T>
1918 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919public:
1920 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1921#define OPENMP_CLAUSE(Name, Class) \
1922 void Visit##Class(const Class *C);
1923#include "clang/Basic/OpenMPKinds.def"
1924};
1925
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001926void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1927 Visitor->AddStmt(C->getCondition());
1928}
1929
Alexey Bataev568a8332014-03-06 06:15:19 +00001930void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1931 Visitor->AddStmt(C->getNumThreads());
1932}
1933
Alexey Bataev62c87d22014-03-21 04:51:18 +00001934void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1935 Visitor->AddStmt(C->getSafelen());
1936}
1937
Alexander Musman8bd31e62014-05-27 15:12:19 +00001938void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1939 Visitor->AddStmt(C->getNumForLoops());
1940}
1941
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001943
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001944void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1945
Alexey Bataev756c1962013-09-24 03:17:45 +00001946template<typename T>
1947void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001948 for (const auto *I : Node->varlists())
1949 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001950}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951
1952void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001955void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1956 const OMPFirstprivateClause *C) {
1957 VisitOMPClauseList(C);
1958}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001959void OMPClauseEnqueue::VisitOMPLastprivateClause(
1960 const OMPLastprivateClause *C) {
1961 VisitOMPClauseList(C);
1962}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001963void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001964 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001965}
Alexander Musman8dba6642014-04-22 13:09:42 +00001966void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1967 VisitOMPClauseList(C);
1968 Visitor->AddStmt(C->getStep());
1969}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001970void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1971 VisitOMPClauseList(C);
1972 Visitor->AddStmt(C->getAlignment());
1973}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001974void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1975 VisitOMPClauseList(C);
1976}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001977}
Alexey Bataev756c1962013-09-24 03:17:45 +00001978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1980 unsigned size = WL.size();
1981 OMPClauseEnqueue Visitor(this);
1982 Visitor.Visit(S);
1983 if (size == WL.size())
1984 return;
1985 // Now reverse the entries we just added. This will match the DFS
1986 // ordering performed by the worklist.
1987 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1988 std::reverse(I, E);
1989}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1992}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddDecl(B->getBlockDecl());
1995}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 EnqueueChildren(E);
1998 AddTypeLoc(E->getTypeSourceInfo());
1999}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2001 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 E = S->body_rend(); I != E; ++I) {
2003 AddStmt(*I);
2004 }
2005}
2006void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 AddStmt(S->getSubStmt());
2009 AddDeclarationNameInfo(S);
2010 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2011 AddNestedNameSpecifierLoc(QualifierLoc);
2012}
2013
2014void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2017 AddDeclarationNameInfo(E);
2018 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2019 AddNestedNameSpecifierLoc(QualifierLoc);
2020 if (!E->isImplicitAccess())
2021 AddStmt(E->getBase());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 // Enqueue the initializer , if any.
2025 AddStmt(E->getInitializer());
2026 // Enqueue the array size, if any.
2027 AddStmt(E->getArraySize());
2028 // Enqueue the allocated type.
2029 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2030 // Enqueue the placement arguments.
2031 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2032 AddStmt(E->getPlacementArg(I-1));
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2036 AddStmt(CE->getArg(I-1));
2037 AddStmt(CE->getCallee());
2038 AddStmt(CE->getArg(0));
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2041 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 // Visit the name of the type being destroyed.
2043 AddTypeLoc(E->getDestroyedTypeInfo());
2044 // Visit the scope type that looks disturbingly like the nested-name-specifier
2045 // but isn't.
2046 AddTypeLoc(E->getScopeTypeInfo());
2047 // Visit the nested-name-specifier.
2048 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2049 AddNestedNameSpecifierLoc(QualifierLoc);
2050 // Visit base expression.
2051 AddStmt(E->getBase());
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2054 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 AddTypeLoc(E->getTypeSourceInfo());
2056}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2058 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 AddTypeLoc(E->getTypeSourceInfo());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 EnqueueChildren(E);
2064 if (E->isTypeOperand())
2065 AddTypeLoc(E->getTypeOperandSourceInfo());
2066}
2067
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2069 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 EnqueueChildren(E);
2075 if (E->isTypeOperand())
2076 AddTypeLoc(E->getTypeOperandSourceInfo());
2077}
2078
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 EnqueueChildren(S);
2081 AddDecl(S->getExceptionDecl());
2082}
2083
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 if (DR->hasExplicitTemplateArgs()) {
2086 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2087 }
2088 WL.push_back(DeclRefExprParts(DR, Parent));
2089}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2091 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2093 AddDeclarationNameInfo(E);
2094 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 unsigned size = WL.size();
2098 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002099 for (const auto *D : S->decls()) {
2100 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 isFirst = false;
2102 }
2103 if (size == WL.size())
2104 return;
2105 // Now reverse the entries we just added. This will match the DFS
2106 // ordering performed by the worklist.
2107 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2108 std::reverse(I, E);
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 D = E->designators_rbegin(), DEnd = E->designators_rend();
2114 D != DEnd; ++D) {
2115 if (D->isFieldDesignator()) {
2116 if (FieldDecl *Field = D->getField())
2117 AddMemberRef(Field, D->getFieldLoc());
2118 continue;
2119 }
2120 if (D->isArrayDesignator()) {
2121 AddStmt(E->getArrayIndex(*D));
2122 continue;
2123 }
2124 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2125 AddStmt(E->getArrayRangeEnd(*D));
2126 AddStmt(E->getArrayRangeStart(*D));
2127 }
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 EnqueueChildren(E);
2131 AddTypeLoc(E->getTypeInfoAsWritten());
2132}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 AddStmt(FS->getBody());
2135 AddStmt(FS->getInc());
2136 AddStmt(FS->getCond());
2137 AddDecl(FS->getConditionVariable());
2138 AddStmt(FS->getInit());
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2142}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 AddStmt(If->getElse());
2145 AddStmt(If->getThen());
2146 AddStmt(If->getCond());
2147 AddDecl(If->getConditionVariable());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 // We care about the syntactic form of the initializer list, only.
2151 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2152 IE = Syntactic;
2153 EnqueueChildren(IE);
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 WL.push_back(MemberExprParts(M, Parent));
2157
2158 // If the base of the member access expression is an implicit 'this', don't
2159 // visit it.
2160 // FIXME: If we ever want to show these implicit accesses, this will be
2161 // unfortunate. However, clang_getCursor() relies on this behavior.
2162 if (!M->isImplicitAccess())
2163 AddStmt(M->getBase());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 AddTypeLoc(E->getEncodedTypeSourceInfo());
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 EnqueueChildren(M);
2170 AddTypeLoc(M->getClassReceiverTypeInfo());
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 // Visit the components of the offsetof expression.
2174 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2175 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2176 const OffsetOfNode &Node = E->getComponent(I-1);
2177 switch (Node.getKind()) {
2178 case OffsetOfNode::Array:
2179 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2180 break;
2181 case OffsetOfNode::Field:
2182 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2183 break;
2184 case OffsetOfNode::Identifier:
2185 case OffsetOfNode::Base:
2186 continue;
2187 }
2188 }
2189 // Visit the type into which we're computing the offset.
2190 AddTypeLoc(E->getTypeSourceInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2194 WL.push_back(OverloadExprParts(E, Parent));
2195}
2196void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 EnqueueChildren(E);
2199 if (E->isArgumentType())
2200 AddTypeLoc(E->getArgumentTypeInfo());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(S);
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(S->getBody());
2207 AddStmt(S->getCond());
2208 AddDecl(S->getConditionVariable());
2209}
2210
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(W->getBody());
2213 AddStmt(W->getCond());
2214 AddDecl(W->getConditionVariable());
2215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 for (unsigned I = E->getNumArgs(); I > 0; --I)
2219 AddTypeLoc(E->getArg(I-1));
2220}
2221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddTypeLoc(E->getQueriedTypeSourceInfo());
2224}
2225
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 EnqueueChildren(E);
2228}
2229
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 VisitOverloadExpr(U);
2232 if (!U->isImplicitAccess())
2233 AddStmt(U->getBase());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddStmt(E->getSubExpr());
2237 AddTypeLoc(E->getWrittenTypeInfo());
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 WL.push_back(SizeOfPackExprParts(E, Parent));
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 // If the opaque value has a source expression, just transparently
2244 // visit that. This is useful for (e.g.) pseudo-object expressions.
2245 if (Expr *SourceExpr = E->getSourceExpr())
2246 return Visit(SourceExpr);
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddStmt(E->getBody());
2250 WL.push_back(LambdaExprParts(E, Parent));
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 // Treat the expression like its syntactic form.
2254 Visit(E->getSyntacticForm());
2255}
2256
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002257void EnqueueVisitor::VisitOMPExecutableDirective(
2258 const OMPExecutableDirective *D) {
2259 EnqueueChildren(D);
2260 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2261 E = D->clauses().end();
2262 I != E; ++I)
2263 EnqueueChildren(*I);
2264}
2265
2266void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2267 VisitOMPExecutableDirective(D);
2268}
2269
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002270void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2271 VisitOMPExecutableDirective(D);
2272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2276}
2277
2278bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2279 if (RegionOfInterest.isValid()) {
2280 SourceRange Range = getRawCursorExtent(C);
2281 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2282 return false;
2283 }
2284 return true;
2285}
2286
2287bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2288 while (!WL.empty()) {
2289 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002290 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002291
2292 // Set the Parent field, then back to its old value once we're done.
2293 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2294
2295 switch (LI.getKind()) {
2296 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 if (!D)
2299 continue;
2300
2301 // For now, perform default visitation for Decls.
2302 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2303 cast<DeclVisit>(&LI)->isFirst())))
2304 return true;
2305
2306 continue;
2307 }
2308 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2309 const ASTTemplateArgumentListInfo *ArgList =
2310 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2311 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2312 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2313 Arg != ArgEnd; ++Arg) {
2314 if (VisitTemplateArgumentLoc(*Arg))
2315 return true;
2316 }
2317 continue;
2318 }
2319 case VisitorJob::TypeLocVisitKind: {
2320 // Perform default visitation for TypeLocs.
2321 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 if (LabelStmt *stmt = LS->getStmt()) {
2328 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2329 TU))) {
2330 return true;
2331 }
2332 }
2333 continue;
2334 }
2335
2336 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2337 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2338 if (VisitNestedNameSpecifierLoc(V->get()))
2339 return true;
2340 continue;
2341 }
2342
2343 case VisitorJob::DeclarationNameInfoVisitKind: {
2344 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2345 ->get()))
2346 return true;
2347 continue;
2348 }
2349 case VisitorJob::MemberRefVisitKind: {
2350 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2351 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2352 return true;
2353 continue;
2354 }
2355 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002357 if (!S)
2358 continue;
2359
2360 // Update the current cursor.
2361 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2362 if (!IsInRegionOfInterest(Cursor))
2363 continue;
2364 switch (Visitor(Cursor, Parent, ClientData)) {
2365 case CXChildVisit_Break: return true;
2366 case CXChildVisit_Continue: break;
2367 case CXChildVisit_Recurse:
2368 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002369 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 EnqueueWorkList(WL, S);
2371 break;
2372 }
2373 continue;
2374 }
2375 case VisitorJob::MemberExprPartsKind: {
2376 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002378
2379 // Visit the nested-name-specifier
2380 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2381 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2382 return true;
2383
2384 // Visit the declaration name.
2385 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2386 return true;
2387
2388 // Visit the explicitly-specified template arguments, if any.
2389 if (M->hasExplicitTemplateArgs()) {
2390 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2391 *ArgEnd = Arg + M->getNumTemplateArgs();
2392 Arg != ArgEnd; ++Arg) {
2393 if (VisitTemplateArgumentLoc(*Arg))
2394 return true;
2395 }
2396 }
2397 continue;
2398 }
2399 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 // Visit nested-name-specifier, if present.
2402 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2403 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2404 return true;
2405 // Visit declaration name.
2406 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2407 return true;
2408 continue;
2409 }
2410 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 // Visit the nested-name-specifier.
2413 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2414 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2415 return true;
2416 // Visit the declaration name.
2417 if (VisitDeclarationNameInfo(O->getNameInfo()))
2418 return true;
2419 // Visit the overloaded declaration reference.
2420 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2421 return true;
2422 continue;
2423 }
2424 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 NamedDecl *Pack = E->getPack();
2427 if (isa<TemplateTypeParmDecl>(Pack)) {
2428 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2429 E->getPackLoc(), TU)))
2430 return true;
2431
2432 continue;
2433 }
2434
2435 if (isa<TemplateTemplateParmDecl>(Pack)) {
2436 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2437 E->getPackLoc(), TU)))
2438 return true;
2439
2440 continue;
2441 }
2442
2443 // Non-type template parameter packs and function parameter packs are
2444 // treated like DeclRefExpr cursors.
2445 continue;
2446 }
2447
2448 case VisitorJob::LambdaExprPartsKind: {
2449 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2452 CEnd = E->explicit_capture_end();
2453 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002454 // FIXME: Lambda init-captures.
2455 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002457
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2459 C->getLocation(),
2460 TU)))
2461 return true;
2462 }
2463
2464 // Visit parameters and return type, if present.
2465 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2466 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2467 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2468 // Visit the whole type.
2469 if (Visit(TL))
2470 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002471 } else if (FunctionProtoTypeLoc Proto =
2472 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 if (E->hasExplicitParameters()) {
2474 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002475 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2476 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 return true;
2478 } else {
2479 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002480 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 return true;
2482 }
2483 }
2484 }
2485 break;
2486 }
2487
2488 case VisitorJob::PostChildrenVisitKind:
2489 if (PostChildrenVisitor(Parent, ClientData))
2490 return true;
2491 break;
2492 }
2493 }
2494 return false;
2495}
2496
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002498 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 if (!WorkListFreeList.empty()) {
2500 WL = WorkListFreeList.back();
2501 WL->clear();
2502 WorkListFreeList.pop_back();
2503 }
2504 else {
2505 WL = new VisitorWorkList();
2506 WorkListCache.push_back(WL);
2507 }
2508 EnqueueWorkList(*WL, S);
2509 bool result = RunVisitorWorkList(*WL);
2510 WorkListFreeList.push_back(WL);
2511 return result;
2512}
2513
2514namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002515typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002516RefNamePieces
2517buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2518 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2519 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2521 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2522 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2523
2524 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2525
2526 RefNamePieces Pieces;
2527
2528 if (WantQualifier && QLoc.isValid())
2529 Pieces.push_back(QLoc);
2530
2531 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2532 Pieces.push_back(NI.getLoc());
2533
2534 if (WantTemplateArgs && TemplateArgs)
2535 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2536 TemplateArgs->RAngleLoc));
2537
2538 if (Kind == DeclarationName::CXXOperatorName) {
2539 Pieces.push_back(SourceLocation::getFromRawEncoding(
2540 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2541 Pieces.push_back(SourceLocation::getFromRawEncoding(
2542 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2543 }
2544
2545 if (WantSinglePiece) {
2546 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2547 Pieces.clear();
2548 Pieces.push_back(R);
2549 }
2550
2551 return Pieces;
2552}
2553}
2554
2555//===----------------------------------------------------------------------===//
2556// Misc. API hooks.
2557//===----------------------------------------------------------------------===//
2558
2559static llvm::sys::Mutex EnableMultithreadingMutex;
2560static bool EnabledMultithreading;
2561
Chad Rosier05c71aa2013-03-27 18:28:23 +00002562static void fatal_error_handler(void *user_data, const std::string& reason,
2563 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002564 // Write the result out to stderr avoiding errs() because raw_ostreams can
2565 // call report_fatal_error.
2566 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2567 ::abort();
2568}
2569
2570extern "C" {
2571CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2572 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 // We use crash recovery to make some of our APIs more reliable, implicitly
2574 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002575 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2576 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002577
2578 // Enable support for multithreading in LLVM.
2579 {
2580 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2581 if (!EnabledMultithreading) {
Craig Topper69186e72014-06-08 08:38:04 +00002582 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00002583 llvm::llvm_start_multithreaded();
2584 EnabledMultithreading = true;
2585 }
2586 }
2587
2588 CIndexer *CIdxr = new CIndexer();
2589 if (excludeDeclarationsFromPCH)
2590 CIdxr->setOnlyLocalDecls();
2591 if (displayDiagnostics)
2592 CIdxr->setDisplayDiagnostics();
2593
2594 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2595 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2596 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2597 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2598 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2599 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2600
2601 return CIdxr;
2602}
2603
2604void clang_disposeIndex(CXIndex CIdx) {
2605 if (CIdx)
2606 delete static_cast<CIndexer *>(CIdx);
2607}
2608
2609void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2610 if (CIdx)
2611 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2612}
2613
2614unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2615 if (CIdx)
2616 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2617 return 0;
2618}
2619
2620void clang_toggleCrashRecovery(unsigned isEnabled) {
2621 if (isEnabled)
2622 llvm::CrashRecoveryContext::Enable();
2623 else
2624 llvm::CrashRecoveryContext::Disable();
2625}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002626
Guy Benyei11169dd2012-12-18 14:30:41 +00002627CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2628 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002629 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002630 enum CXErrorCode Result =
2631 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002632 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002633 assert((TU && Result == CXError_Success) ||
2634 (!TU && Result != CXError_Success));
2635 return TU;
2636}
2637
2638enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2639 const char *ast_filename,
2640 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002641 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002642 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002643
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002644 if (!CIdx || !ast_filename || !out_TU)
2645 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002646
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002647 LOG_FUNC_SECTION {
2648 *Log << ast_filename;
2649 }
2650
Guy Benyei11169dd2012-12-18 14:30:41 +00002651 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2652 FileSystemOptions FileSystemOpts;
2653
2654 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002656 CXXIdx->getOnlyLocalDecls(), None,
2657 /*CaptureDiagnostics=*/true,
2658 /*AllowPCHWithCompilerErrors=*/true,
2659 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002660 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2661 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002662}
2663
2664unsigned clang_defaultEditingTranslationUnitOptions() {
2665 return CXTranslationUnit_PrecompiledPreamble |
2666 CXTranslationUnit_CacheCompletionResults;
2667}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668
Guy Benyei11169dd2012-12-18 14:30:41 +00002669CXTranslationUnit
2670clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2671 const char *source_filename,
2672 int num_command_line_args,
2673 const char * const *command_line_args,
2674 unsigned num_unsaved_files,
2675 struct CXUnsavedFile *unsaved_files) {
2676 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2677 return clang_parseTranslationUnit(CIdx, source_filename,
2678 command_line_args, num_command_line_args,
2679 unsaved_files, num_unsaved_files,
2680 Options);
2681}
2682
2683struct ParseTranslationUnitInfo {
2684 CXIndex CIdx;
2685 const char *source_filename;
2686 const char *const *command_line_args;
2687 int num_command_line_args;
2688 struct CXUnsavedFile *unsaved_files;
2689 unsigned num_unsaved_files;
2690 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002691 CXTranslationUnit *out_TU;
2692 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002693};
2694static void clang_parseTranslationUnit_Impl(void *UserData) {
2695 ParseTranslationUnitInfo *PTUI =
2696 static_cast<ParseTranslationUnitInfo*>(UserData);
2697 CXIndex CIdx = PTUI->CIdx;
2698 const char *source_filename = PTUI->source_filename;
2699 const char * const *command_line_args = PTUI->command_line_args;
2700 int num_command_line_args = PTUI->num_command_line_args;
2701 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2702 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2703 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002704 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002705
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002706 // Set up the initial return values.
2707 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002708 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002709 PTUI->result = CXError_Failure;
2710
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002711 // Check arguments.
2712 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002713 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002714 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716 }
2717
Guy Benyei11169dd2012-12-18 14:30:41 +00002718 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2719
2720 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2721 setThreadBackgroundPriority();
2722
2723 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2724 // FIXME: Add a flag for modules.
2725 TranslationUnitKind TUKind
2726 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002727 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 = options & CXTranslationUnit_CacheCompletionResults;
2729 bool IncludeBriefCommentsInCodeCompletion
2730 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2731 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2732 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2733
2734 // Configure the diagnostics.
2735 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002736 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002737
2738 // Recover resources if we crash before exiting this function.
2739 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2740 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2741 DiagCleanup(Diags.getPtr());
2742
Ahmed Charlesb8984322014-03-07 20:03:18 +00002743 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2744 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002745
2746 // Recover resources if we crash before exiting this function.
2747 llvm::CrashRecoveryContextCleanupRegistrar<
2748 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2749
2750 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2751 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2752 const llvm::MemoryBuffer *Buffer
2753 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2754 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2755 Buffer));
2756 }
2757
Ahmed Charlesb8984322014-03-07 20:03:18 +00002758 std::unique_ptr<std::vector<const char *>> Args(
2759 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002760
2761 // Recover resources if we crash before exiting this method.
2762 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2763 ArgsCleanup(Args.get());
2764
2765 // Since the Clang C library is primarily used by batch tools dealing with
2766 // (often very broken) source code, where spell-checking can have a
2767 // significant negative impact on performance (particularly when
2768 // precompiled headers are involved), we disable it by default.
2769 // Only do this if we haven't found a spell-checking-related argument.
2770 bool FoundSpellCheckingArgument = false;
2771 for (int I = 0; I != num_command_line_args; ++I) {
2772 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2773 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2774 FoundSpellCheckingArgument = true;
2775 break;
2776 }
2777 }
2778 if (!FoundSpellCheckingArgument)
2779 Args->push_back("-fno-spell-checking");
2780
2781 Args->insert(Args->end(), command_line_args,
2782 command_line_args + num_command_line_args);
2783
2784 // The 'source_filename' argument is optional. If the caller does not
2785 // specify it then it is assumed that the source file is specified
2786 // in the actual argument list.
2787 // Put the source file after command_line_args otherwise if '-x' flag is
2788 // present it will be unused.
2789 if (source_filename)
2790 Args->push_back(source_filename);
2791
2792 // Do we need the detailed preprocessing record?
2793 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2794 Args->push_back("-Xclang");
2795 Args->push_back("-detailed-preprocessing-record");
2796 }
2797
2798 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002799 std::unique_ptr<ASTUnit> ErrUnit;
2800 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002801 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002802 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2803 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2804 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2805 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2806 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2807 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002808
2809 if (NumErrors != Diags->getClient()->getNumErrors()) {
2810 // Make sure to check that 'Unit' is non-NULL.
2811 if (CXXIdx->getDisplayDiagnostics())
2812 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2813 }
2814
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2816 PTUI->result = CXError_ASTReadError;
2817 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002818 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2820 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002821}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002822
2823CXTranslationUnit
2824clang_parseTranslationUnit(CXIndex CIdx,
2825 const char *source_filename,
2826 const char *const *command_line_args,
2827 int num_command_line_args,
2828 struct CXUnsavedFile *unsaved_files,
2829 unsigned num_unsaved_files,
2830 unsigned options) {
2831 CXTranslationUnit TU;
2832 enum CXErrorCode Result = clang_parseTranslationUnit2(
2833 CIdx, source_filename, command_line_args, num_command_line_args,
2834 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002835 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002836 assert((TU && Result == CXError_Success) ||
2837 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002838 return TU;
2839}
2840
2841enum CXErrorCode clang_parseTranslationUnit2(
2842 CXIndex CIdx,
2843 const char *source_filename,
2844 const char *const *command_line_args,
2845 int num_command_line_args,
2846 struct CXUnsavedFile *unsaved_files,
2847 unsigned num_unsaved_files,
2848 unsigned options,
2849 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002850 LOG_FUNC_SECTION {
2851 *Log << source_filename << ": ";
2852 for (int i = 0; i != num_command_line_args; ++i)
2853 *Log << command_line_args[i] << " ";
2854 }
2855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2857 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 num_unsaved_files, options, out_TU,
2859 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 llvm::CrashRecoveryContext CRC;
2861
2862 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2863 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2864 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2865 fprintf(stderr, " 'command_line_args' : [");
2866 for (int i = 0; i != num_command_line_args; ++i) {
2867 if (i)
2868 fprintf(stderr, ", ");
2869 fprintf(stderr, "'%s'", command_line_args[i]);
2870 }
2871 fprintf(stderr, "],\n");
2872 fprintf(stderr, " 'unsaved_files' : [");
2873 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2874 if (i)
2875 fprintf(stderr, ", ");
2876 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2877 unsaved_files[i].Length);
2878 }
2879 fprintf(stderr, "],\n");
2880 fprintf(stderr, " 'options' : %d,\n", options);
2881 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002882
2883 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002885 if (CXTranslationUnit *TU = PTUI.out_TU)
2886 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 }
2888
2889 return PTUI.result;
2890}
2891
2892unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2893 return CXSaveTranslationUnit_None;
2894}
2895
2896namespace {
2897
2898struct SaveTranslationUnitInfo {
2899 CXTranslationUnit TU;
2900 const char *FileName;
2901 unsigned options;
2902 CXSaveError result;
2903};
2904
2905}
2906
2907static void clang_saveTranslationUnit_Impl(void *UserData) {
2908 SaveTranslationUnitInfo *STUI =
2909 static_cast<SaveTranslationUnitInfo*>(UserData);
2910
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002911 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2913 setThreadBackgroundPriority();
2914
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002915 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2917}
2918
2919int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2920 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002921 LOG_FUNC_SECTION {
2922 *Log << TU << ' ' << FileName;
2923 }
2924
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002925 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002926 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002928 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002930 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2932 if (!CXXUnit->hasSema())
2933 return CXSaveError_InvalidTU;
2934
2935 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2936
2937 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2938 getenv("LIBCLANG_NOTHREADS")) {
2939 clang_saveTranslationUnit_Impl(&STUI);
2940
2941 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2942 PrintLibclangResourceUsage(TU);
2943
2944 return STUI.result;
2945 }
2946
2947 // We have an AST that has invalid nodes due to compiler errors.
2948 // Use a crash recovery thread for protection.
2949
2950 llvm::CrashRecoveryContext CRC;
2951
2952 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2953 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2954 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2955 fprintf(stderr, " 'options' : %d,\n", options);
2956 fprintf(stderr, "}\n");
2957
2958 return CXSaveError_Unknown;
2959
2960 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2961 PrintLibclangResourceUsage(TU);
2962 }
2963
2964 return STUI.result;
2965}
2966
2967void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2968 if (CTUnit) {
2969 // If the translation unit has been marked as unsafe to free, just discard
2970 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2972 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 return;
2974
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002975 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002976 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2978 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002979 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002980 delete CTUnit;
2981 }
2982}
2983
2984unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2985 return CXReparse_None;
2986}
2987
2988struct ReparseTranslationUnitInfo {
2989 CXTranslationUnit TU;
2990 unsigned num_unsaved_files;
2991 struct CXUnsavedFile *unsaved_files;
2992 unsigned options;
2993 int result;
2994};
2995
2996static void clang_reparseTranslationUnit_Impl(void *UserData) {
2997 ReparseTranslationUnitInfo *RTUI =
2998 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003000
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3003 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3004 unsigned options = RTUI->options;
3005 (void) options;
3006
3007 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003008 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003009 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010 RTUI->result = CXError_InvalidArguments;
3011 return;
3012 }
Craig Topper69186e72014-06-08 08:38:04 +00003013 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003014 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003015 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003016 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003017
3018 // Reset the associated diagnostics.
3019 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003020 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003021
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003022 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3024 setThreadBackgroundPriority();
3025
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003026 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003028
3029 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3030 new std::vector<ASTUnit::RemappedFile>());
3031
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 // Recover resources if we crash before exiting this function.
3033 llvm::CrashRecoveryContextCleanupRegistrar<
3034 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3035
3036 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3037 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3038 const llvm::MemoryBuffer *Buffer
3039 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3040 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3041 Buffer));
3042 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003044 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 RTUI->result = CXError_Success;
3046 else if (isASTReadError(CXXUnit))
3047 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003048}
3049
3050int clang_reparseTranslationUnit(CXTranslationUnit TU,
3051 unsigned num_unsaved_files,
3052 struct CXUnsavedFile *unsaved_files,
3053 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003054 LOG_FUNC_SECTION {
3055 *Log << TU;
3056 }
3057
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003059 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003060
3061 if (getenv("LIBCLANG_NOTHREADS")) {
3062 clang_reparseTranslationUnit_Impl(&RTUI);
3063 return RTUI.result;
3064 }
3065
3066 llvm::CrashRecoveryContext CRC;
3067
3068 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3069 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003070 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3073 PrintLibclangResourceUsage(TU);
3074
3075 return RTUI.result;
3076}
3077
3078
3079CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003080 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003082 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003083 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003084
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003085 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003086 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003087}
3088
3089CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003090 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003091 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003092 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003093 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003094
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003095 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3097}
3098
3099} // end: extern "C"
3100
3101//===----------------------------------------------------------------------===//
3102// CXFile Operations.
3103//===----------------------------------------------------------------------===//
3104
3105extern "C" {
3106CXString clang_getFileName(CXFile SFile) {
3107 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003108 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003109
3110 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003111 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003112}
3113
3114time_t clang_getFileTime(CXFile SFile) {
3115 if (!SFile)
3116 return 0;
3117
3118 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3119 return FEnt->getModificationTime();
3120}
3121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003122CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003123 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003124 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003125 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003127
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003128 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003129
3130 FileManager &FMgr = CXXUnit->getFileManager();
3131 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3132}
3133
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003134unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3135 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003136 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003137 LOG_BAD_TU(TU);
3138 return 0;
3139 }
3140
3141 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return 0;
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003145 FileEntry *FEnt = static_cast<FileEntry *>(file);
3146 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3147 .isFileMultipleIncludeGuarded(FEnt);
3148}
3149
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003150int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3151 if (!file || !outID)
3152 return 1;
3153
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003155 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3156 outID->data[0] = ID.getDevice();
3157 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003158 outID->data[2] = FEnt->getModificationTime();
3159 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003160}
3161
Guy Benyei11169dd2012-12-18 14:30:41 +00003162} // end: extern "C"
3163
3164//===----------------------------------------------------------------------===//
3165// CXCursor Operations.
3166//===----------------------------------------------------------------------===//
3167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168static const Decl *getDeclFromExpr(const Stmt *E) {
3169 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 return getDeclFromExpr(CE->getSubExpr());
3171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 if (PRE->isExplicitProperty())
3180 return PRE->getExplicitProperty();
3181 // It could be messaging both getter and setter as in:
3182 // ++myobj.myprop;
3183 // in which case prefer to associate the setter since it is less obvious
3184 // from inspecting the source that the setter is going to get called.
3185 if (PRE->isMessagingSetter())
3186 return PRE->getImplicitPropertySetter();
3187 return PRE->getImplicitPropertyGetter();
3188 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (Expr *Src = OVE->getSourceExpr())
3193 return getDeclFromExpr(Src);
3194
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 if (!CE->isElidable())
3199 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return OME->getMethodDecl();
3202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3207 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003208 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3210 isa<ParmVarDecl>(SizeOfPack->getPack()))
3211 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003212
3213 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003214}
3215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216static SourceLocation getLocationFromExpr(const Expr *E) {
3217 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return getLocationFromExpr(CE->getSubExpr());
3219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003228 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003230 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return PropRef->getLocation();
3232
3233 return E->getLocStart();
3234}
3235
3236extern "C" {
3237
3238unsigned clang_visitChildren(CXCursor parent,
3239 CXCursorVisitor visitor,
3240 CXClientData client_data) {
3241 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3242 /*VisitPreprocessorLast=*/false);
3243 return CursorVis.VisitChildren(parent);
3244}
3245
3246#ifndef __has_feature
3247#define __has_feature(x) 0
3248#endif
3249#if __has_feature(blocks)
3250typedef enum CXChildVisitResult
3251 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3252
3253static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3254 CXClientData client_data) {
3255 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3256 return block(cursor, parent);
3257}
3258#else
3259// If we are compiled with a compiler that doesn't have native blocks support,
3260// define and call the block manually, so the
3261typedef struct _CXChildVisitResult
3262{
3263 void *isa;
3264 int flags;
3265 int reserved;
3266 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3267 CXCursor);
3268} *CXCursorVisitorBlock;
3269
3270static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3271 CXClientData client_data) {
3272 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3273 return block->invoke(block, cursor, parent);
3274}
3275#endif
3276
3277
3278unsigned clang_visitChildrenWithBlock(CXCursor parent,
3279 CXCursorVisitorBlock block) {
3280 return clang_visitChildren(parent, visitWithBlock, block);
3281}
3282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003285 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const ObjCPropertyImplDecl *PropImpl =
3290 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 }
3300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003301 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003302 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003304 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3306 // and returns different names. NamedDecl returns the class name and
3307 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003308 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
3310 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003311 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003312
3313 SmallString<1024> S;
3314 llvm::raw_svector_ostream os(S);
3315 ND->printName(os);
3316
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003317 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318}
3319
3320CXString clang_getCursorSpelling(CXCursor C) {
3321 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003322 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
3324 if (clang_isReference(C.kind)) {
3325 switch (C.kind) {
3326 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003328 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003331 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003332 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 }
3334 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003335 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003337 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(Type && "Missing type decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 getAsString());
3349 }
3350 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(Template && "Missing template decl");
3353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 assert(NS && "Missing namespace decl");
3360
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003361 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 }
3363
3364 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 assert(Field && "Missing member decl");
3367
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
3370
3371 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003372 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 assert(Label && "Missing label");
3374
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003375 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 case CXCursor_OverloadedDeclRef: {
3379 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3381 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003383 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003385 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 OverloadedTemplateStorage *Ovl
3388 = Storage.get<OverloadedTemplateStorage*>();
3389 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003390 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393
3394 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003395 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 assert(Var && "Missing variable decl");
3397
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003398 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400
3401 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003402 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 }
3404 }
3405
3406 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003407 const Expr *E = getCursorExpr(C);
3408
3409 if (C.kind == CXCursor_ObjCStringLiteral ||
3410 C.kind == CXCursor_StringLiteral) {
3411 const StringLiteral *SLit;
3412 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3413 SLit = OSL->getString();
3414 } else {
3415 SLit = cast<StringLiteral>(E);
3416 }
3417 SmallString<256> Buf;
3418 llvm::raw_svector_ostream OS(Buf);
3419 SLit->outputString(OS);
3420 return cxstring::createDup(OS.str());
3421 }
3422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 if (D)
3425 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003426 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 }
3428
3429 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003430 const Stmt *S = getCursorStmt(C);
3431 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
3437 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 ->getNameStart());
3440
3441 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003442 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 ->getNameStart());
3444
3445 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003446 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447
3448 if (clang_isDeclaration(C.kind))
3449 return getDeclSpelling(getCursorDecl(C));
3450
3451 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003452 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455
3456 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003457 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003458 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 }
3460
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003461 if (C.kind == CXCursor_PackedAttr) {
3462 return cxstring::createRef("packed");
3463 }
3464
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003466}
3467
3468CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3469 unsigned pieceIndex,
3470 unsigned options) {
3471 if (clang_Cursor_isNull(C))
3472 return clang_getNullRange();
3473
3474 ASTContext &Ctx = getCursorContext(C);
3475
3476 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003477 const Stmt *S = getCursorStmt(C);
3478 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 if (pieceIndex > 0)
3480 return clang_getNullRange();
3481 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3482 }
3483
3484 return clang_getNullRange();
3485 }
3486
3487 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003488 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3490 if (pieceIndex >= ME->getNumSelectorLocs())
3491 return clang_getNullRange();
3492 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3493 }
3494 }
3495
3496 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3497 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3500 if (pieceIndex >= MD->getNumSelectorLocs())
3501 return clang_getNullRange();
3502 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3503 }
3504 }
3505
3506 if (C.kind == CXCursor_ObjCCategoryDecl ||
3507 C.kind == CXCursor_ObjCCategoryImplDecl) {
3508 if (pieceIndex > 0)
3509 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3512 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3515 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3516 }
3517
3518 if (C.kind == CXCursor_ModuleImportDecl) {
3519 if (pieceIndex > 0)
3520 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const ImportDecl *ImportD =
3522 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3524 if (!Locs.empty())
3525 return cxloc::translateSourceRange(Ctx,
3526 SourceRange(Locs.front(), Locs.back()));
3527 }
3528 return clang_getNullRange();
3529 }
3530
3531 // FIXME: A CXCursor_InclusionDirective should give the location of the
3532 // filename, but we don't keep track of this.
3533
3534 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3535 // but we don't keep track of this.
3536
3537 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3538 // but we don't keep track of this.
3539
3540 // Default handling, give the location of the cursor.
3541
3542 if (pieceIndex > 0)
3543 return clang_getNullRange();
3544
3545 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3546 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3547 return cxloc::translateSourceRange(Ctx, Loc);
3548}
3549
3550CXString clang_getCursorDisplayName(CXCursor C) {
3551 if (!clang_isDeclaration(C.kind))
3552 return clang_getCursorSpelling(C);
3553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003556 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003557
3558 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 D = FunTmpl->getTemplatedDecl();
3561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003562 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 SmallString<64> Str;
3564 llvm::raw_svector_ostream OS(Str);
3565 OS << *Function;
3566 if (Function->getPrimaryTemplate())
3567 OS << "<>";
3568 OS << "(";
3569 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3570 if (I)
3571 OS << ", ";
3572 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3573 }
3574
3575 if (Function->isVariadic()) {
3576 if (Function->getNumParams())
3577 OS << ", ";
3578 OS << "...";
3579 }
3580 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003581 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 }
3583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003584 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 SmallString<64> Str;
3586 llvm::raw_svector_ostream OS(Str);
3587 OS << *ClassTemplate;
3588 OS << "<";
3589 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3590 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3591 if (I)
3592 OS << ", ";
3593
3594 NamedDecl *Param = Params->getParam(I);
3595 if (Param->getIdentifier()) {
3596 OS << Param->getIdentifier()->getName();
3597 continue;
3598 }
3599
3600 // There is no parameter name, which makes this tricky. Try to come up
3601 // with something useful that isn't too long.
3602 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3603 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3604 else if (NonTypeTemplateParmDecl *NTTP
3605 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3606 OS << NTTP->getType().getAsString(Policy);
3607 else
3608 OS << "template<...> class";
3609 }
3610
3611 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003612 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003615 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3617 // If the type was explicitly written, use that.
3618 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003620
Benjamin Kramer9170e912013-02-22 15:46:01 +00003621 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 llvm::raw_svector_ostream OS(Str);
3623 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003624 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 ClassSpec->getTemplateArgs().data(),
3626 ClassSpec->getTemplateArgs().size(),
3627 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 return clang_getCursorSpelling(C);
3632}
3633
3634CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3635 switch (Kind) {
3636 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003764 case CXCursor_ObjCSelfExpr:
3765 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003882 case CXCursor_PackedAttr:
3883 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003884 case CXCursor_PureAttr:
3885 return cxstring::createRef("attribute(pure)");
3886 case CXCursor_ConstAttr:
3887 return cxstring::createRef("attribute(const)");
3888 case CXCursor_NoDuplicateAttr:
3889 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003890 case CXCursor_CUDAConstantAttr:
3891 return cxstring::createRef("attribute(constant)");
3892 case CXCursor_CUDADeviceAttr:
3893 return cxstring::createRef("attribute(device)");
3894 case CXCursor_CUDAGlobalAttr:
3895 return cxstring::createRef("attribute(global)");
3896 case CXCursor_CUDAHostAttr:
3897 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003946 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003947 return cxstring::createRef("OMPParallelDirective");
3948 case CXCursor_OMPSimdDirective:
3949 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 }
3951
3952 llvm_unreachable("Unhandled CXCursorKind");
3953}
3954
3955struct GetCursorData {
3956 SourceLocation TokenBeginLoc;
3957 bool PointsAtMacroArgExpansion;
3958 bool VisitedObjCPropertyImplDecl;
3959 SourceLocation VisitedDeclaratorDeclStartLoc;
3960 CXCursor &BestCursor;
3961
3962 GetCursorData(SourceManager &SM,
3963 SourceLocation tokenBegin, CXCursor &outputCursor)
3964 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3965 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3966 VisitedObjCPropertyImplDecl = false;
3967 }
3968};
3969
3970static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3971 CXCursor parent,
3972 CXClientData client_data) {
3973 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3974 CXCursor *BestCursor = &Data->BestCursor;
3975
3976 // If we point inside a macro argument we should provide info of what the
3977 // token is so use the actual cursor, don't replace it with a macro expansion
3978 // cursor.
3979 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3980 return CXChildVisit_Recurse;
3981
3982 if (clang_isDeclaration(cursor.kind)) {
3983 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003984 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3986 if (MD->isImplicit())
3987 return CXChildVisit_Break;
3988
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003989 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3991 // Check that when we have multiple @class references in the same line,
3992 // that later ones do not override the previous ones.
3993 // If we have:
3994 // @class Foo, Bar;
3995 // source ranges for both start at '@', so 'Bar' will end up overriding
3996 // 'Foo' even though the cursor location was at 'Foo'.
3997 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3998 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003999 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4001 if (PrevID != ID &&
4002 !PrevID->isThisDeclarationADefinition() &&
4003 !ID->isThisDeclarationADefinition())
4004 return CXChildVisit_Break;
4005 }
4006
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004007 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4009 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4010 // Check that when we have multiple declarators in the same line,
4011 // that later ones do not override the previous ones.
4012 // If we have:
4013 // int Foo, Bar;
4014 // source ranges for both start at 'int', so 'Bar' will end up overriding
4015 // 'Foo' even though the cursor location was at 'Foo'.
4016 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4017 return CXChildVisit_Break;
4018 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4019
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004020 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4022 (void)PropImp;
4023 // Check that when we have multiple @synthesize in the same line,
4024 // that later ones do not override the previous ones.
4025 // If we have:
4026 // @synthesize Foo, Bar;
4027 // source ranges for both start at '@', so 'Bar' will end up overriding
4028 // 'Foo' even though the cursor location was at 'Foo'.
4029 if (Data->VisitedObjCPropertyImplDecl)
4030 return CXChildVisit_Break;
4031 Data->VisitedObjCPropertyImplDecl = true;
4032 }
4033 }
4034
4035 if (clang_isExpression(cursor.kind) &&
4036 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004037 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 // Avoid having the cursor of an expression replace the declaration cursor
4039 // when the expression source range overlaps the declaration range.
4040 // This can happen for C++ constructor expressions whose range generally
4041 // include the variable declaration, e.g.:
4042 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4043 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4044 D->getLocation() == Data->TokenBeginLoc)
4045 return CXChildVisit_Break;
4046 }
4047 }
4048
4049 // If our current best cursor is the construction of a temporary object,
4050 // don't replace that cursor with a type reference, because we want
4051 // clang_getCursor() to point at the constructor.
4052 if (clang_isExpression(BestCursor->kind) &&
4053 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4054 cursor.kind == CXCursor_TypeRef) {
4055 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4056 // as having the actual point on the type reference.
4057 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4058 return CXChildVisit_Recurse;
4059 }
4060
4061 *BestCursor = cursor;
4062 return CXChildVisit_Recurse;
4063}
4064
4065CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004066 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004067 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004069 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004070
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004071 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4073
4074 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4075 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4076
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004077 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 CXFile SearchFile;
4079 unsigned SearchLine, SearchColumn;
4080 CXFile ResultFile;
4081 unsigned ResultLine, ResultColumn;
4082 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4083 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4084 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004085
4086 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4087 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004088 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004089 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 SearchFileName = clang_getFileName(SearchFile);
4091 ResultFileName = clang_getFileName(ResultFile);
4092 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4093 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004094 *Log << llvm::format("(%s:%d:%d) = %s",
4095 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4096 clang_getCString(KindSpelling))
4097 << llvm::format("(%s:%d:%d):%s%s",
4098 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4099 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 clang_disposeString(SearchFileName);
4101 clang_disposeString(ResultFileName);
4102 clang_disposeString(KindSpelling);
4103 clang_disposeString(USR);
4104
4105 CXCursor Definition = clang_getCursorDefinition(Result);
4106 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4107 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4108 CXString DefinitionKindSpelling
4109 = clang_getCursorKindSpelling(Definition.kind);
4110 CXFile DefinitionFile;
4111 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004112 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004113 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004115 *Log << llvm::format(" -> %s(%s:%d:%d)",
4116 clang_getCString(DefinitionKindSpelling),
4117 clang_getCString(DefinitionFileName),
4118 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 clang_disposeString(DefinitionFileName);
4120 clang_disposeString(DefinitionKindSpelling);
4121 }
4122 }
4123
4124 return Result;
4125}
4126
4127CXCursor clang_getNullCursor(void) {
4128 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4129}
4130
4131unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004132 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4133 // can't set consistently. For example, when visiting a DeclStmt we will set
4134 // it but we don't set it on the result of clang_getCursorDefinition for
4135 // a reference of the same declaration.
4136 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4137 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4138 // to provide that kind of info.
4139 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004140 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004141 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004142 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004143
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 return X == Y;
4145}
4146
4147unsigned clang_hashCursor(CXCursor C) {
4148 unsigned Index = 0;
4149 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4150 Index = 1;
4151
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004152 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 std::make_pair(C.kind, C.data[Index]));
4154}
4155
4156unsigned clang_isInvalid(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4158}
4159
4160unsigned clang_isDeclaration(enum CXCursorKind K) {
4161 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4162 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4163}
4164
4165unsigned clang_isReference(enum CXCursorKind K) {
4166 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4167}
4168
4169unsigned clang_isExpression(enum CXCursorKind K) {
4170 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4171}
4172
4173unsigned clang_isStatement(enum CXCursorKind K) {
4174 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4175}
4176
4177unsigned clang_isAttribute(enum CXCursorKind K) {
4178 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4179}
4180
4181unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4182 return K == CXCursor_TranslationUnit;
4183}
4184
4185unsigned clang_isPreprocessing(enum CXCursorKind K) {
4186 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4187}
4188
4189unsigned clang_isUnexposed(enum CXCursorKind K) {
4190 switch (K) {
4191 case CXCursor_UnexposedDecl:
4192 case CXCursor_UnexposedExpr:
4193 case CXCursor_UnexposedStmt:
4194 case CXCursor_UnexposedAttr:
4195 return true;
4196 default:
4197 return false;
4198 }
4199}
4200
4201CXCursorKind clang_getCursorKind(CXCursor C) {
4202 return C.kind;
4203}
4204
4205CXSourceLocation clang_getCursorLocation(CXCursor C) {
4206 if (clang_isReference(C.kind)) {
4207 switch (C.kind) {
4208 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 = getCursorObjCSuperClassRef(C);
4211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 = getCursorObjCProtocolRef(C);
4217 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4218 }
4219
4220 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004221 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 = getCursorObjCClassRef(C);
4223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4224 }
4225
4226 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4229 }
4230
4231 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 std::pair<const TemplateDecl *, SourceLocation> P =
4233 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4235 }
4236
4237 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004238 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4240 }
4241
4242 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004243 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4245 }
4246
4247 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004248 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4250 }
4251
4252 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004253 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 if (!BaseSpec)
4255 return clang_getNullLocation();
4256
4257 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4258 return cxloc::translateSourceLocation(getCursorContext(C),
4259 TSInfo->getTypeLoc().getBeginLoc());
4260
4261 return cxloc::translateSourceLocation(getCursorContext(C),
4262 BaseSpec->getLocStart());
4263 }
4264
4265 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004266 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4268 }
4269
4270 case CXCursor_OverloadedDeclRef:
4271 return cxloc::translateSourceLocation(getCursorContext(C),
4272 getCursorOverloadedDeclRef(C).second);
4273
4274 default:
4275 // FIXME: Need a way to enumerate all non-reference cases.
4276 llvm_unreachable("Missed a reference kind");
4277 }
4278 }
4279
4280 if (clang_isExpression(C.kind))
4281 return cxloc::translateSourceLocation(getCursorContext(C),
4282 getLocationFromExpr(getCursorExpr(C)));
4283
4284 if (clang_isStatement(C.kind))
4285 return cxloc::translateSourceLocation(getCursorContext(C),
4286 getCursorStmt(C)->getLocStart());
4287
4288 if (C.kind == CXCursor_PreprocessingDirective) {
4289 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4290 return cxloc::translateSourceLocation(getCursorContext(C), L);
4291 }
4292
4293 if (C.kind == CXCursor_MacroExpansion) {
4294 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004295 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 return cxloc::translateSourceLocation(getCursorContext(C), L);
4297 }
4298
4299 if (C.kind == CXCursor_MacroDefinition) {
4300 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4301 return cxloc::translateSourceLocation(getCursorContext(C), L);
4302 }
4303
4304 if (C.kind == CXCursor_InclusionDirective) {
4305 SourceLocation L
4306 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4307 return cxloc::translateSourceLocation(getCursorContext(C), L);
4308 }
4309
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004310 if (clang_isAttribute(C.kind)) {
4311 SourceLocation L
4312 = cxcursor::getCursorAttr(C)->getLocation();
4313 return cxloc::translateSourceLocation(getCursorContext(C), L);
4314 }
4315
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 if (!clang_isDeclaration(C.kind))
4317 return clang_getNullLocation();
4318
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004319 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 if (!D)
4321 return clang_getNullLocation();
4322
4323 SourceLocation Loc = D->getLocation();
4324 // FIXME: Multiple variables declared in a single declaration
4325 // currently lack the information needed to correctly determine their
4326 // ranges when accounting for the type-specifier. We use context
4327 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4328 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004329 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 if (!cxcursor::isFirstInDeclGroup(C))
4331 Loc = VD->getLocation();
4332 }
4333
4334 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004335 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 Loc = MD->getSelectorStartLoc();
4337
4338 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4339}
4340
4341} // end extern "C"
4342
4343CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4344 assert(TU);
4345
4346 // Guard against an invalid SourceLocation, or we may assert in one
4347 // of the following calls.
4348 if (SLoc.isInvalid())
4349 return clang_getNullCursor();
4350
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004351 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352
4353 // Translate the given source location to make it point at the beginning of
4354 // the token under the cursor.
4355 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4356 CXXUnit->getASTContext().getLangOpts());
4357
4358 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4359 if (SLoc.isValid()) {
4360 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4361 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4362 /*VisitPreprocessorLast=*/true,
4363 /*VisitIncludedEntities=*/false,
4364 SourceLocation(SLoc));
4365 CursorVis.visitFileRegion();
4366 }
4367
4368 return Result;
4369}
4370
4371static SourceRange getRawCursorExtent(CXCursor C) {
4372 if (clang_isReference(C.kind)) {
4373 switch (C.kind) {
4374 case CXCursor_ObjCSuperClassRef:
4375 return getCursorObjCSuperClassRef(C).second;
4376
4377 case CXCursor_ObjCProtocolRef:
4378 return getCursorObjCProtocolRef(C).second;
4379
4380 case CXCursor_ObjCClassRef:
4381 return getCursorObjCClassRef(C).second;
4382
4383 case CXCursor_TypeRef:
4384 return getCursorTypeRef(C).second;
4385
4386 case CXCursor_TemplateRef:
4387 return getCursorTemplateRef(C).second;
4388
4389 case CXCursor_NamespaceRef:
4390 return getCursorNamespaceRef(C).second;
4391
4392 case CXCursor_MemberRef:
4393 return getCursorMemberRef(C).second;
4394
4395 case CXCursor_CXXBaseSpecifier:
4396 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4397
4398 case CXCursor_LabelRef:
4399 return getCursorLabelRef(C).second;
4400
4401 case CXCursor_OverloadedDeclRef:
4402 return getCursorOverloadedDeclRef(C).second;
4403
4404 case CXCursor_VariableRef:
4405 return getCursorVariableRef(C).second;
4406
4407 default:
4408 // FIXME: Need a way to enumerate all non-reference cases.
4409 llvm_unreachable("Missed a reference kind");
4410 }
4411 }
4412
4413 if (clang_isExpression(C.kind))
4414 return getCursorExpr(C)->getSourceRange();
4415
4416 if (clang_isStatement(C.kind))
4417 return getCursorStmt(C)->getSourceRange();
4418
4419 if (clang_isAttribute(C.kind))
4420 return getCursorAttr(C)->getRange();
4421
4422 if (C.kind == CXCursor_PreprocessingDirective)
4423 return cxcursor::getCursorPreprocessingDirective(C);
4424
4425 if (C.kind == CXCursor_MacroExpansion) {
4426 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004427 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 return TU->mapRangeFromPreamble(Range);
4429 }
4430
4431 if (C.kind == CXCursor_MacroDefinition) {
4432 ASTUnit *TU = getCursorASTUnit(C);
4433 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4434 return TU->mapRangeFromPreamble(Range);
4435 }
4436
4437 if (C.kind == CXCursor_InclusionDirective) {
4438 ASTUnit *TU = getCursorASTUnit(C);
4439 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4440 return TU->mapRangeFromPreamble(Range);
4441 }
4442
4443 if (C.kind == CXCursor_TranslationUnit) {
4444 ASTUnit *TU = getCursorASTUnit(C);
4445 FileID MainID = TU->getSourceManager().getMainFileID();
4446 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4447 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4448 return SourceRange(Start, End);
4449 }
4450
4451 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004452 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 if (!D)
4454 return SourceRange();
4455
4456 SourceRange R = D->getSourceRange();
4457 // FIXME: Multiple variables declared in a single declaration
4458 // currently lack the information needed to correctly determine their
4459 // ranges when accounting for the type-specifier. We use context
4460 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4461 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004462 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 if (!cxcursor::isFirstInDeclGroup(C))
4464 R.setBegin(VD->getLocation());
4465 }
4466 return R;
4467 }
4468 return SourceRange();
4469}
4470
4471/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4472/// the decl-specifier-seq for declarations.
4473static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4474 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004475 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 if (!D)
4477 return SourceRange();
4478
4479 SourceRange R = D->getSourceRange();
4480
4481 // Adjust the start of the location for declarations preceded by
4482 // declaration specifiers.
4483 SourceLocation StartLoc;
4484 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4485 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4486 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004487 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4489 StartLoc = TI->getTypeLoc().getLocStart();
4490 }
4491
4492 if (StartLoc.isValid() && R.getBegin().isValid() &&
4493 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4494 R.setBegin(StartLoc);
4495
4496 // FIXME: Multiple variables declared in a single declaration
4497 // currently lack the information needed to correctly determine their
4498 // ranges when accounting for the type-specifier. We use context
4499 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4500 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 if (!cxcursor::isFirstInDeclGroup(C))
4503 R.setBegin(VD->getLocation());
4504 }
4505
4506 return R;
4507 }
4508
4509 return getRawCursorExtent(C);
4510}
4511
4512extern "C" {
4513
4514CXSourceRange clang_getCursorExtent(CXCursor C) {
4515 SourceRange R = getRawCursorExtent(C);
4516 if (R.isInvalid())
4517 return clang_getNullRange();
4518
4519 return cxloc::translateSourceRange(getCursorContext(C), R);
4520}
4521
4522CXCursor clang_getCursorReferenced(CXCursor C) {
4523 if (clang_isInvalid(C.kind))
4524 return clang_getNullCursor();
4525
4526 CXTranslationUnit tu = getCursorTU(C);
4527 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004528 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 if (!D)
4530 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004531 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 if (const ObjCPropertyImplDecl *PropImpl =
4534 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4536 return MakeCXCursor(Property, tu);
4537
4538 return C;
4539 }
4540
4541 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004542 const Expr *E = getCursorExpr(C);
4543 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 if (D) {
4545 CXCursor declCursor = MakeCXCursor(D, tu);
4546 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4547 declCursor);
4548 return declCursor;
4549 }
4550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return MakeCursorOverloadedDeclRef(Ovl, tu);
4553
4554 return clang_getNullCursor();
4555 }
4556
4557 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004558 const Stmt *S = getCursorStmt(C);
4559 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 if (LabelDecl *label = Goto->getLabel())
4561 if (LabelStmt *labelS = label->getStmt())
4562 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4563
4564 return clang_getNullCursor();
4565 }
4566
4567 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004568 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return MakeMacroDefinitionCursor(Def, tu);
4570 }
4571
4572 if (!clang_isReference(C.kind))
4573 return clang_getNullCursor();
4574
4575 switch (C.kind) {
4576 case CXCursor_ObjCSuperClassRef:
4577 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4578
4579 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004580 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4581 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return MakeCXCursor(Def, tu);
4583
4584 return MakeCXCursor(Prot, tu);
4585 }
4586
4587 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004588 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4589 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 return MakeCXCursor(Def, tu);
4591
4592 return MakeCXCursor(Class, tu);
4593 }
4594
4595 case CXCursor_TypeRef:
4596 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4597
4598 case CXCursor_TemplateRef:
4599 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4600
4601 case CXCursor_NamespaceRef:
4602 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4603
4604 case CXCursor_MemberRef:
4605 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4606
4607 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004608 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4610 tu ));
4611 }
4612
4613 case CXCursor_LabelRef:
4614 // FIXME: We end up faking the "parent" declaration here because we
4615 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004616 return MakeCXCursor(getCursorLabelRef(C).first,
4617 cxtu::getASTUnit(tu)->getASTContext()
4618 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 tu);
4620
4621 case CXCursor_OverloadedDeclRef:
4622 return C;
4623
4624 case CXCursor_VariableRef:
4625 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4626
4627 default:
4628 // We would prefer to enumerate all non-reference cursor kinds here.
4629 llvm_unreachable("Unhandled reference cursor kind");
4630 }
4631}
4632
4633CXCursor clang_getCursorDefinition(CXCursor C) {
4634 if (clang_isInvalid(C.kind))
4635 return clang_getNullCursor();
4636
4637 CXTranslationUnit TU = getCursorTU(C);
4638
4639 bool WasReference = false;
4640 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4641 C = clang_getCursorReferenced(C);
4642 WasReference = true;
4643 }
4644
4645 if (C.kind == CXCursor_MacroExpansion)
4646 return clang_getCursorReferenced(C);
4647
4648 if (!clang_isDeclaration(C.kind))
4649 return clang_getNullCursor();
4650
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004651 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 if (!D)
4653 return clang_getNullCursor();
4654
4655 switch (D->getKind()) {
4656 // Declaration kinds that don't really separate the notions of
4657 // declaration and definition.
4658 case Decl::Namespace:
4659 case Decl::Typedef:
4660 case Decl::TypeAlias:
4661 case Decl::TypeAliasTemplate:
4662 case Decl::TemplateTypeParm:
4663 case Decl::EnumConstant:
4664 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004665 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 case Decl::IndirectField:
4667 case Decl::ObjCIvar:
4668 case Decl::ObjCAtDefsField:
4669 case Decl::ImplicitParam:
4670 case Decl::ParmVar:
4671 case Decl::NonTypeTemplateParm:
4672 case Decl::TemplateTemplateParm:
4673 case Decl::ObjCCategoryImpl:
4674 case Decl::ObjCImplementation:
4675 case Decl::AccessSpec:
4676 case Decl::LinkageSpec:
4677 case Decl::ObjCPropertyImpl:
4678 case Decl::FileScopeAsm:
4679 case Decl::StaticAssert:
4680 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004681 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 case Decl::Label: // FIXME: Is this right??
4683 case Decl::ClassScopeFunctionSpecialization:
4684 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004685 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 return C;
4687
4688 // Declaration kinds that don't make any sense here, but are
4689 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004690 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case Decl::TranslationUnit:
4692 break;
4693
4694 // Declaration kinds for which the definition is not resolvable.
4695 case Decl::UnresolvedUsingTypename:
4696 case Decl::UnresolvedUsingValue:
4697 break;
4698
4699 case Decl::UsingDirective:
4700 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4701 TU);
4702
4703 case Decl::NamespaceAlias:
4704 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4705
4706 case Decl::Enum:
4707 case Decl::Record:
4708 case Decl::CXXRecord:
4709 case Decl::ClassTemplateSpecialization:
4710 case Decl::ClassTemplatePartialSpecialization:
4711 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4712 return MakeCXCursor(Def, TU);
4713 return clang_getNullCursor();
4714
4715 case Decl::Function:
4716 case Decl::CXXMethod:
4717 case Decl::CXXConstructor:
4718 case Decl::CXXDestructor:
4719 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004720 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004722 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 return clang_getNullCursor();
4724 }
4725
Larisse Voufo39a1e502013-08-06 01:03:05 +00004726 case Decl::Var:
4727 case Decl::VarTemplateSpecialization:
4728 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 return MakeCXCursor(Def, TU);
4732 return clang_getNullCursor();
4733 }
4734
4735 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004736 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4738 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4739 return clang_getNullCursor();
4740 }
4741
4742 case Decl::ClassTemplate: {
4743 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4744 ->getDefinition())
4745 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4746 TU);
4747 return clang_getNullCursor();
4748 }
4749
Larisse Voufo39a1e502013-08-06 01:03:05 +00004750 case Decl::VarTemplate: {
4751 if (VarDecl *Def =
4752 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4753 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4754 return clang_getNullCursor();
4755 }
4756
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case Decl::Using:
4758 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4759 D->getLocation(), TU);
4760
4761 case Decl::UsingShadow:
4762 return clang_getCursorDefinition(
4763 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4764 TU));
4765
4766 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 if (Method->isThisDeclarationADefinition())
4769 return C;
4770
4771 // Dig out the method definition in the associated
4772 // @implementation, if we have it.
4773 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4776 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4777 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4778 Method->isInstanceMethod()))
4779 if (Def->isThisDeclarationADefinition())
4780 return MakeCXCursor(Def, TU);
4781
4782 return clang_getNullCursor();
4783 }
4784
4785 case Decl::ObjCCategory:
4786 if (ObjCCategoryImplDecl *Impl
4787 = cast<ObjCCategoryDecl>(D)->getImplementation())
4788 return MakeCXCursor(Impl, TU);
4789 return clang_getNullCursor();
4790
4791 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 return MakeCXCursor(Def, TU);
4794 return clang_getNullCursor();
4795
4796 case Decl::ObjCInterface: {
4797 // There are two notions of a "definition" for an Objective-C
4798 // class: the interface and its implementation. When we resolved a
4799 // reference to an Objective-C class, produce the @interface as
4800 // the definition; when we were provided with the interface,
4801 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004802 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004804 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 return MakeCXCursor(Def, TU);
4806 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4807 return MakeCXCursor(Impl, TU);
4808 return clang_getNullCursor();
4809 }
4810
4811 case Decl::ObjCProperty:
4812 // FIXME: We don't really know where to find the
4813 // ObjCPropertyImplDecls that implement this property.
4814 return clang_getNullCursor();
4815
4816 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004819 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 return MakeCXCursor(Def, TU);
4821
4822 return clang_getNullCursor();
4823
4824 case Decl::Friend:
4825 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4826 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4827 return clang_getNullCursor();
4828
4829 case Decl::FriendTemplate:
4830 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4831 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4832 return clang_getNullCursor();
4833 }
4834
4835 return clang_getNullCursor();
4836}
4837
4838unsigned clang_isCursorDefinition(CXCursor C) {
4839 if (!clang_isDeclaration(C.kind))
4840 return 0;
4841
4842 return clang_getCursorDefinition(C) == C;
4843}
4844
4845CXCursor clang_getCanonicalCursor(CXCursor C) {
4846 if (!clang_isDeclaration(C.kind))
4847 return C;
4848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 if (const Decl *D = getCursorDecl(C)) {
4850 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4852 return MakeCXCursor(CatD, getCursorTU(C));
4853
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4855 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004856 return MakeCXCursor(IFD, getCursorTU(C));
4857
4858 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4859 }
4860
4861 return C;
4862}
4863
4864int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4865 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4866}
4867
4868unsigned clang_getNumOverloadedDecls(CXCursor C) {
4869 if (C.kind != CXCursor_OverloadedDeclRef)
4870 return 0;
4871
4872 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 return E->getNumDecls();
4875
4876 if (OverloadedTemplateStorage *S
4877 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4878 return S->size();
4879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004880 const Decl *D = Storage.get<const Decl *>();
4881 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 return Using->shadow_size();
4883
4884 return 0;
4885}
4886
4887CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4888 if (cursor.kind != CXCursor_OverloadedDeclRef)
4889 return clang_getNullCursor();
4890
4891 if (index >= clang_getNumOverloadedDecls(cursor))
4892 return clang_getNullCursor();
4893
4894 CXTranslationUnit TU = getCursorTU(cursor);
4895 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 return MakeCXCursor(E->decls_begin()[index], TU);
4898
4899 if (OverloadedTemplateStorage *S
4900 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4901 return MakeCXCursor(S->begin()[index], TU);
4902
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004903 const Decl *D = Storage.get<const Decl *>();
4904 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 // FIXME: This is, unfortunately, linear time.
4906 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4907 std::advance(Pos, index);
4908 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4909 }
4910
4911 return clang_getNullCursor();
4912}
4913
4914void clang_getDefinitionSpellingAndExtent(CXCursor C,
4915 const char **startBuf,
4916 const char **endBuf,
4917 unsigned *startLine,
4918 unsigned *startColumn,
4919 unsigned *endLine,
4920 unsigned *endColumn) {
4921 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004922 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4924
4925 SourceManager &SM = FD->getASTContext().getSourceManager();
4926 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4927 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4928 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4929 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4930 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4931 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4932}
4933
4934
4935CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4936 unsigned PieceIndex) {
4937 RefNamePieces Pieces;
4938
4939 switch (C.kind) {
4940 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004941 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4943 E->getQualifierLoc().getSourceRange());
4944 break;
4945
4946 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004947 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4949 E->getQualifierLoc().getSourceRange(),
4950 E->getOptionalExplicitTemplateArgs());
4951 break;
4952
4953 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004954 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004956 const Expr *Callee = OCE->getCallee();
4957 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 Callee = ICE->getSubExpr();
4959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004960 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4962 DRE->getQualifierLoc().getSourceRange());
4963 }
4964 break;
4965
4966 default:
4967 break;
4968 }
4969
4970 if (Pieces.empty()) {
4971 if (PieceIndex == 0)
4972 return clang_getCursorExtent(C);
4973 } else if (PieceIndex < Pieces.size()) {
4974 SourceRange R = Pieces[PieceIndex];
4975 if (R.isValid())
4976 return cxloc::translateSourceRange(getCursorContext(C), R);
4977 }
4978
4979 return clang_getNullRange();
4980}
4981
4982void clang_enableStackTraces(void) {
4983 llvm::sys::PrintStackTraceOnErrorSignal();
4984}
4985
4986void clang_executeOnThread(void (*fn)(void*), void *user_data,
4987 unsigned stack_size) {
4988 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4989}
4990
4991} // end: extern "C"
4992
4993//===----------------------------------------------------------------------===//
4994// Token-based Operations.
4995//===----------------------------------------------------------------------===//
4996
4997/* CXToken layout:
4998 * int_data[0]: a CXTokenKind
4999 * int_data[1]: starting token location
5000 * int_data[2]: token length
5001 * int_data[3]: reserved
5002 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5003 * otherwise unused.
5004 */
5005extern "C" {
5006
5007CXTokenKind clang_getTokenKind(CXToken CXTok) {
5008 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5009}
5010
5011CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5012 switch (clang_getTokenKind(CXTok)) {
5013 case CXToken_Identifier:
5014 case CXToken_Keyword:
5015 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005016 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 ->getNameStart());
5018
5019 case CXToken_Literal: {
5020 // We have stashed the starting pointer in the ptr_data field. Use it.
5021 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005022 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 }
5024
5025 case CXToken_Punctuation:
5026 case CXToken_Comment:
5027 break;
5028 }
5029
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005030 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005031 LOG_BAD_TU(TU);
5032 return cxstring::createEmpty();
5033 }
5034
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 // We have to find the starting buffer pointer the hard way, by
5036 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005037 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005039 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005040
5041 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5042 std::pair<FileID, unsigned> LocInfo
5043 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5044 bool Invalid = false;
5045 StringRef Buffer
5046 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5047 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005048 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005049
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005050 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005051}
5052
5053CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005054 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005055 LOG_BAD_TU(TU);
5056 return clang_getNullLocation();
5057 }
5058
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005059 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 if (!CXXUnit)
5061 return clang_getNullLocation();
5062
5063 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5064 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5065}
5066
5067CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005068 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005069 LOG_BAD_TU(TU);
5070 return clang_getNullRange();
5071 }
5072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005073 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 if (!CXXUnit)
5075 return clang_getNullRange();
5076
5077 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5078 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5079}
5080
5081static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5082 SmallVectorImpl<CXToken> &CXTokens) {
5083 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5084 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005085 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005087 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005088
5089 // Cannot tokenize across files.
5090 if (BeginLocInfo.first != EndLocInfo.first)
5091 return;
5092
5093 // Create a lexer
5094 bool Invalid = false;
5095 StringRef Buffer
5096 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5097 if (Invalid)
5098 return;
5099
5100 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5101 CXXUnit->getASTContext().getLangOpts(),
5102 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5103 Lex.SetCommentRetentionState(true);
5104
5105 // Lex tokens until we hit the end of the range.
5106 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5107 Token Tok;
5108 bool previousWasAt = false;
5109 do {
5110 // Lex the next token
5111 Lex.LexFromRawLexer(Tok);
5112 if (Tok.is(tok::eof))
5113 break;
5114
5115 // Initialize the CXToken.
5116 CXToken CXTok;
5117
5118 // - Common fields
5119 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5120 CXTok.int_data[2] = Tok.getLength();
5121 CXTok.int_data[3] = 0;
5122
5123 // - Kind-specific fields
5124 if (Tok.isLiteral()) {
5125 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005126 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 } else if (Tok.is(tok::raw_identifier)) {
5128 // Lookup the identifier to determine whether we have a keyword.
5129 IdentifierInfo *II
5130 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5131
5132 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5133 CXTok.int_data[0] = CXToken_Keyword;
5134 }
5135 else {
5136 CXTok.int_data[0] = Tok.is(tok::identifier)
5137 ? CXToken_Identifier
5138 : CXToken_Keyword;
5139 }
5140 CXTok.ptr_data = II;
5141 } else if (Tok.is(tok::comment)) {
5142 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005143 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 } else {
5145 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005146 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 }
5148 CXTokens.push_back(CXTok);
5149 previousWasAt = Tok.is(tok::at);
5150 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5151}
5152
5153void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5154 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005155 LOG_FUNC_SECTION {
5156 *Log << TU << ' ' << Range;
5157 }
5158
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005160 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 if (NumTokens)
5162 *NumTokens = 0;
5163
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005164 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005165 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005166 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005167 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005168
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005169 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 if (!CXXUnit || !Tokens || !NumTokens)
5171 return;
5172
5173 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5174
5175 SourceRange R = cxloc::translateCXSourceRange(Range);
5176 if (R.isInvalid())
5177 return;
5178
5179 SmallVector<CXToken, 32> CXTokens;
5180 getTokens(CXXUnit, R, CXTokens);
5181
5182 if (CXTokens.empty())
5183 return;
5184
5185 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5186 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5187 *NumTokens = CXTokens.size();
5188}
5189
5190void clang_disposeTokens(CXTranslationUnit TU,
5191 CXToken *Tokens, unsigned NumTokens) {
5192 free(Tokens);
5193}
5194
5195} // end: extern "C"
5196
5197//===----------------------------------------------------------------------===//
5198// Token annotation APIs.
5199//===----------------------------------------------------------------------===//
5200
Guy Benyei11169dd2012-12-18 14:30:41 +00005201static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5202 CXCursor parent,
5203 CXClientData client_data);
5204static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5205 CXClientData client_data);
5206
5207namespace {
5208class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 CXToken *Tokens;
5210 CXCursor *Cursors;
5211 unsigned NumTokens;
5212 unsigned TokIdx;
5213 unsigned PreprocessingTokIdx;
5214 CursorVisitor AnnotateVis;
5215 SourceManager &SrcMgr;
5216 bool HasContextSensitiveKeywords;
5217
5218 struct PostChildrenInfo {
5219 CXCursor Cursor;
5220 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005221 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 unsigned BeforeChildrenTokenIdx;
5223 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005224 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005225
5226 CXToken &getTok(unsigned Idx) {
5227 assert(Idx < NumTokens);
5228 return Tokens[Idx];
5229 }
5230 const CXToken &getTok(unsigned Idx) const {
5231 assert(Idx < NumTokens);
5232 return Tokens[Idx];
5233 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 bool MoreTokens() const { return TokIdx < NumTokens; }
5235 unsigned NextToken() const { return TokIdx; }
5236 void AdvanceToken() { ++TokIdx; }
5237 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005238 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 }
5240 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005241 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 }
5243 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005244 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 }
5246
5247 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005248 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 SourceRange);
5250
5251public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005252 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005253 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005254 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005256 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 AnnotateTokensVisitor, this,
5258 /*VisitPreprocessorLast=*/true,
5259 /*VisitIncludedEntities=*/false,
5260 RegionOfInterest,
5261 /*VisitDeclsOnly=*/false,
5262 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005263 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 HasContextSensitiveKeywords(false) { }
5265
5266 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5267 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5268 bool postVisitChildren(CXCursor cursor);
5269 void AnnotateTokens();
5270
5271 /// \brief Determine whether the annotator saw any cursors that have
5272 /// context-sensitive keywords.
5273 bool hasContextSensitiveKeywords() const {
5274 return HasContextSensitiveKeywords;
5275 }
5276
5277 ~AnnotateTokensWorker() {
5278 assert(PostChildrenInfos.empty());
5279 }
5280};
5281}
5282
5283void AnnotateTokensWorker::AnnotateTokens() {
5284 // Walk the AST within the region of interest, annotating tokens
5285 // along the way.
5286 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005287}
Guy Benyei11169dd2012-12-18 14:30:41 +00005288
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005289static inline void updateCursorAnnotation(CXCursor &Cursor,
5290 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005291 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005293 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005294}
5295
5296/// \brief It annotates and advances tokens with a cursor until the comparison
5297//// between the cursor location and the source range is the same as
5298/// \arg compResult.
5299///
5300/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5301/// Pass RangeOverlap to annotate tokens inside a range.
5302void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5303 RangeComparisonResult compResult,
5304 SourceRange range) {
5305 while (MoreTokens()) {
5306 const unsigned I = NextToken();
5307 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005308 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5309 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005310
5311 SourceLocation TokLoc = GetTokenLoc(I);
5312 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005313 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 AdvanceToken();
5315 continue;
5316 }
5317 break;
5318 }
5319}
5320
5321/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005322/// \returns true if it advanced beyond all macro tokens, false otherwise.
5323bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 CXCursor updateC,
5325 RangeComparisonResult compResult,
5326 SourceRange range) {
5327 assert(MoreTokens());
5328 assert(isFunctionMacroToken(NextToken()) &&
5329 "Should be called only for macro arg tokens");
5330
5331 // This works differently than annotateAndAdvanceTokens; because expanded
5332 // macro arguments can have arbitrary translation-unit source order, we do not
5333 // advance the token index one by one until a token fails the range test.
5334 // We only advance once past all of the macro arg tokens if all of them
5335 // pass the range test. If one of them fails we keep the token index pointing
5336 // at the start of the macro arg tokens so that the failing token will be
5337 // annotated by a subsequent annotation try.
5338
5339 bool atLeastOneCompFail = false;
5340
5341 unsigned I = NextToken();
5342 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5343 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5344 if (TokLoc.isFileID())
5345 continue; // not macro arg token, it's parens or comma.
5346 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5347 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5348 Cursors[I] = updateC;
5349 } else
5350 atLeastOneCompFail = true;
5351 }
5352
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005353 if (atLeastOneCompFail)
5354 return false;
5355
5356 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5357 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005358}
5359
5360enum CXChildVisitResult
5361AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 SourceRange cursorRange = getRawCursorExtent(cursor);
5363 if (cursorRange.isInvalid())
5364 return CXChildVisit_Recurse;
5365
5366 if (!HasContextSensitiveKeywords) {
5367 // Objective-C properties can have context-sensitive keywords.
5368 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005369 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5371 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5372 }
5373 // Objective-C methods can have context-sensitive keywords.
5374 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5375 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005376 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5378 if (Method->getObjCDeclQualifier())
5379 HasContextSensitiveKeywords = true;
5380 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005381 for (const auto *P : Method->params()) {
5382 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 HasContextSensitiveKeywords = true;
5384 break;
5385 }
5386 }
5387 }
5388 }
5389 }
5390 // C++ methods can have context-sensitive keywords.
5391 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005392 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5394 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5395 HasContextSensitiveKeywords = true;
5396 }
5397 }
5398 // C++ classes can have context-sensitive keywords.
5399 else if (cursor.kind == CXCursor_StructDecl ||
5400 cursor.kind == CXCursor_ClassDecl ||
5401 cursor.kind == CXCursor_ClassTemplate ||
5402 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005403 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 if (D->hasAttr<FinalAttr>())
5405 HasContextSensitiveKeywords = true;
5406 }
5407 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005408
5409 // Don't override a property annotation with its getter/setter method.
5410 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5411 parent.kind == CXCursor_ObjCPropertyDecl)
5412 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005413
5414 if (clang_isPreprocessing(cursor.kind)) {
5415 // Items in the preprocessing record are kept separate from items in
5416 // declarations, so we keep a separate token index.
5417 unsigned SavedTokIdx = TokIdx;
5418 TokIdx = PreprocessingTokIdx;
5419
5420 // Skip tokens up until we catch up to the beginning of the preprocessing
5421 // entry.
5422 while (MoreTokens()) {
5423 const unsigned I = NextToken();
5424 SourceLocation TokLoc = GetTokenLoc(I);
5425 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5426 case RangeBefore:
5427 AdvanceToken();
5428 continue;
5429 case RangeAfter:
5430 case RangeOverlap:
5431 break;
5432 }
5433 break;
5434 }
5435
5436 // Look at all of the tokens within this range.
5437 while (MoreTokens()) {
5438 const unsigned I = NextToken();
5439 SourceLocation TokLoc = GetTokenLoc(I);
5440 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5441 case RangeBefore:
5442 llvm_unreachable("Infeasible");
5443 case RangeAfter:
5444 break;
5445 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005446 // For macro expansions, just note where the beginning of the macro
5447 // expansion occurs.
5448 if (cursor.kind == CXCursor_MacroExpansion) {
5449 if (TokLoc == cursorRange.getBegin())
5450 Cursors[I] = cursor;
5451 AdvanceToken();
5452 break;
5453 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005454 // We may have already annotated macro names inside macro definitions.
5455 if (Cursors[I].kind != CXCursor_MacroExpansion)
5456 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 continue;
5459 }
5460 break;
5461 }
5462
5463 // Save the preprocessing token index; restore the non-preprocessing
5464 // token index.
5465 PreprocessingTokIdx = TokIdx;
5466 TokIdx = SavedTokIdx;
5467 return CXChildVisit_Recurse;
5468 }
5469
5470 if (cursorRange.isInvalid())
5471 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005472
5473 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 const enum CXCursorKind K = clang_getCursorKind(parent);
5476 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005477 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5478 // Attributes are annotated out-of-order, skip tokens until we reach it.
5479 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 ? clang_getNullCursor() : parent;
5481
5482 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5483
5484 // Avoid having the cursor of an expression "overwrite" the annotation of the
5485 // variable declaration that it belongs to.
5486 // This can happen for C++ constructor expressions whose range generally
5487 // include the variable declaration, e.g.:
5488 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005489 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005490 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005491 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 const unsigned I = NextToken();
5493 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5494 E->getLocStart() == D->getLocation() &&
5495 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005496 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 AdvanceToken();
5498 }
5499 }
5500 }
5501
5502 // Before recursing into the children keep some state that we are going
5503 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5504 // extra work after the child nodes are visited.
5505 // Note that we don't call VisitChildren here to avoid traversing statements
5506 // code-recursively which can blow the stack.
5507
5508 PostChildrenInfo Info;
5509 Info.Cursor = cursor;
5510 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005511 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 Info.BeforeChildrenTokenIdx = NextToken();
5513 PostChildrenInfos.push_back(Info);
5514
5515 return CXChildVisit_Recurse;
5516}
5517
5518bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5519 if (PostChildrenInfos.empty())
5520 return false;
5521 const PostChildrenInfo &Info = PostChildrenInfos.back();
5522 if (!clang_equalCursors(Info.Cursor, cursor))
5523 return false;
5524
5525 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5526 const unsigned AfterChildren = NextToken();
5527 SourceRange cursorRange = Info.CursorRange;
5528
5529 // Scan the tokens that are at the end of the cursor, but are not captured
5530 // but the child cursors.
5531 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5532
5533 // Scan the tokens that are at the beginning of the cursor, but are not
5534 // capture by the child cursors.
5535 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5536 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5537 break;
5538
5539 Cursors[I] = cursor;
5540 }
5541
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005542 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5543 // encountered the attribute cursor.
5544 if (clang_isAttribute(cursor.kind))
5545 TokIdx = Info.BeforeReachingCursorIdx;
5546
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 PostChildrenInfos.pop_back();
5548 return false;
5549}
5550
5551static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5552 CXCursor parent,
5553 CXClientData client_data) {
5554 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5555}
5556
5557static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5558 CXClientData client_data) {
5559 return static_cast<AnnotateTokensWorker*>(client_data)->
5560 postVisitChildren(cursor);
5561}
5562
5563namespace {
5564
5565/// \brief Uses the macro expansions in the preprocessing record to find
5566/// and mark tokens that are macro arguments. This info is used by the
5567/// AnnotateTokensWorker.
5568class MarkMacroArgTokensVisitor {
5569 SourceManager &SM;
5570 CXToken *Tokens;
5571 unsigned NumTokens;
5572 unsigned CurIdx;
5573
5574public:
5575 MarkMacroArgTokensVisitor(SourceManager &SM,
5576 CXToken *tokens, unsigned numTokens)
5577 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5578
5579 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5580 if (cursor.kind != CXCursor_MacroExpansion)
5581 return CXChildVisit_Continue;
5582
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005583 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 if (macroRange.getBegin() == macroRange.getEnd())
5585 return CXChildVisit_Continue; // it's not a function macro.
5586
5587 for (; CurIdx < NumTokens; ++CurIdx) {
5588 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5589 macroRange.getBegin()))
5590 break;
5591 }
5592
5593 if (CurIdx == NumTokens)
5594 return CXChildVisit_Break;
5595
5596 for (; CurIdx < NumTokens; ++CurIdx) {
5597 SourceLocation tokLoc = getTokenLoc(CurIdx);
5598 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5599 break;
5600
5601 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5602 }
5603
5604 if (CurIdx == NumTokens)
5605 return CXChildVisit_Break;
5606
5607 return CXChildVisit_Continue;
5608 }
5609
5610private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005611 CXToken &getTok(unsigned Idx) {
5612 assert(Idx < NumTokens);
5613 return Tokens[Idx];
5614 }
5615 const CXToken &getTok(unsigned Idx) const {
5616 assert(Idx < NumTokens);
5617 return Tokens[Idx];
5618 }
5619
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005621 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 }
5623
5624 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5625 // The third field is reserved and currently not used. Use it here
5626 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005627 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 }
5629};
5630
5631} // end anonymous namespace
5632
5633static CXChildVisitResult
5634MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5635 CXClientData client_data) {
5636 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5637 parent);
5638}
5639
5640namespace {
5641 struct clang_annotateTokens_Data {
5642 CXTranslationUnit TU;
5643 ASTUnit *CXXUnit;
5644 CXToken *Tokens;
5645 unsigned NumTokens;
5646 CXCursor *Cursors;
5647 };
5648}
5649
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005650/// \brief Used by \c annotatePreprocessorTokens.
5651/// \returns true if lexing was finished, false otherwise.
5652static bool lexNext(Lexer &Lex, Token &Tok,
5653 unsigned &NextIdx, unsigned NumTokens) {
5654 if (NextIdx >= NumTokens)
5655 return true;
5656
5657 ++NextIdx;
5658 Lex.LexFromRawLexer(Tok);
5659 if (Tok.is(tok::eof))
5660 return true;
5661
5662 return false;
5663}
5664
Guy Benyei11169dd2012-12-18 14:30:41 +00005665static void annotatePreprocessorTokens(CXTranslationUnit TU,
5666 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005667 CXCursor *Cursors,
5668 CXToken *Tokens,
5669 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005670 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005671
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005672 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5674 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005675 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005677 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005678
5679 if (BeginLocInfo.first != EndLocInfo.first)
5680 return;
5681
5682 StringRef Buffer;
5683 bool Invalid = false;
5684 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5685 if (Buffer.empty() || Invalid)
5686 return;
5687
5688 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5689 CXXUnit->getASTContext().getLangOpts(),
5690 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5691 Buffer.end());
5692 Lex.SetCommentRetentionState(true);
5693
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005694 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 // Lex tokens in raw mode until we hit the end of the range, to avoid
5696 // entering #includes or expanding macros.
5697 while (true) {
5698 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5700 break;
5701 unsigned TokIdx = NextIdx-1;
5702 assert(Tok.getLocation() ==
5703 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005704
5705 reprocess:
5706 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707 // We have found a preprocessing directive. Annotate the tokens
5708 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 //
5710 // FIXME: Some simple tests here could identify macro definitions and
5711 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712
5713 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005714 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5715 break;
5716
Craig Topper69186e72014-06-08 08:38:04 +00005717 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005718 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005719 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5720 break;
5721
5722 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005723 IdentifierInfo &II =
5724 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005725 SourceLocation MappedTokLoc =
5726 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5727 MI = getMacroInfo(II, MappedTokLoc, TU);
5728 }
5729 }
5730
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005731 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005733 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5734 finished = true;
5735 break;
5736 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005737 // If we are in a macro definition, check if the token was ever a
5738 // macro name and annotate it if that's the case.
5739 if (MI) {
5740 SourceLocation SaveLoc = Tok.getLocation();
5741 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5742 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5743 Tok.setLocation(SaveLoc);
5744 if (MacroDef)
5745 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5746 Tok.getLocation(), TU);
5747 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005748 } while (!Tok.isAtStartOfLine());
5749
5750 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5751 assert(TokIdx <= LastIdx);
5752 SourceLocation EndLoc =
5753 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5754 CXCursor Cursor =
5755 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5756
5757 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005758 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005759
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005760 if (finished)
5761 break;
5762 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 }
5765}
5766
5767// This gets run a separate thread to avoid stack blowout.
5768static void clang_annotateTokensImpl(void *UserData) {
5769 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5770 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5771 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5772 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5773 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5774
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005775 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5777 setThreadBackgroundPriority();
5778
5779 // Determine the region of interest, which contains all of the tokens.
5780 SourceRange RegionOfInterest;
5781 RegionOfInterest.setBegin(
5782 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5783 RegionOfInterest.setEnd(
5784 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5785 Tokens[NumTokens-1])));
5786
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 // Relex the tokens within the source range to look for preprocessing
5788 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005789 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005790
5791 // If begin location points inside a macro argument, set it to the expansion
5792 // location so we can have the full context when annotating semantically.
5793 {
5794 SourceManager &SM = CXXUnit->getSourceManager();
5795 SourceLocation Loc =
5796 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5797 if (Loc.isMacroID())
5798 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5799 }
5800
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5802 // Search and mark tokens that are macro argument expansions.
5803 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5804 Tokens, NumTokens);
5805 CursorVisitor MacroArgMarker(TU,
5806 MarkMacroArgTokensVisitorDelegate, &Visitor,
5807 /*VisitPreprocessorLast=*/true,
5808 /*VisitIncludedEntities=*/false,
5809 RegionOfInterest);
5810 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5811 }
5812
5813 // Annotate all of the source locations in the region of interest that map to
5814 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005815 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005816
5817 // FIXME: We use a ridiculous stack size here because the data-recursion
5818 // algorithm uses a large stack frame than the non-data recursive version,
5819 // and AnnotationTokensWorker currently transforms the data-recursion
5820 // algorithm back into a traditional recursion by explicitly calling
5821 // VisitChildren(). We will need to remove this explicit recursive call.
5822 W.AnnotateTokens();
5823
5824 // If we ran into any entities that involve context-sensitive keywords,
5825 // take another pass through the tokens to mark them as such.
5826 if (W.hasContextSensitiveKeywords()) {
5827 for (unsigned I = 0; I != NumTokens; ++I) {
5828 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5829 continue;
5830
5831 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5832 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005833 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005834 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5835 if (Property->getPropertyAttributesAsWritten() != 0 &&
5836 llvm::StringSwitch<bool>(II->getName())
5837 .Case("readonly", true)
5838 .Case("assign", true)
5839 .Case("unsafe_unretained", true)
5840 .Case("readwrite", true)
5841 .Case("retain", true)
5842 .Case("copy", true)
5843 .Case("nonatomic", true)
5844 .Case("atomic", true)
5845 .Case("getter", true)
5846 .Case("setter", true)
5847 .Case("strong", true)
5848 .Case("weak", true)
5849 .Default(false))
5850 Tokens[I].int_data[0] = CXToken_Keyword;
5851 }
5852 continue;
5853 }
5854
5855 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5856 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5857 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5858 if (llvm::StringSwitch<bool>(II->getName())
5859 .Case("in", true)
5860 .Case("out", true)
5861 .Case("inout", true)
5862 .Case("oneway", true)
5863 .Case("bycopy", true)
5864 .Case("byref", true)
5865 .Default(false))
5866 Tokens[I].int_data[0] = CXToken_Keyword;
5867 continue;
5868 }
5869
5870 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5871 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5872 Tokens[I].int_data[0] = CXToken_Keyword;
5873 continue;
5874 }
5875 }
5876 }
5877}
5878
5879extern "C" {
5880
5881void clang_annotateTokens(CXTranslationUnit TU,
5882 CXToken *Tokens, unsigned NumTokens,
5883 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005884 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005885 LOG_BAD_TU(TU);
5886 return;
5887 }
5888 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005889 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005891 }
5892
5893 LOG_FUNC_SECTION {
5894 *Log << TU << ' ';
5895 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5896 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5897 *Log << clang_getRange(bloc, eloc);
5898 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005899
5900 // Any token we don't specifically annotate will have a NULL cursor.
5901 CXCursor C = clang_getNullCursor();
5902 for (unsigned I = 0; I != NumTokens; ++I)
5903 Cursors[I] = C;
5904
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005905 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 if (!CXXUnit)
5907 return;
5908
5909 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5910
5911 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5912 llvm::CrashRecoveryContext CRC;
5913 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5914 GetSafetyThreadStackSize() * 2)) {
5915 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5916 }
5917}
5918
5919} // end: extern "C"
5920
5921//===----------------------------------------------------------------------===//
5922// Operations for querying linkage of a cursor.
5923//===----------------------------------------------------------------------===//
5924
5925extern "C" {
5926CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5927 if (!clang_isDeclaration(cursor.kind))
5928 return CXLinkage_Invalid;
5929
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005930 const Decl *D = cxcursor::getCursorDecl(cursor);
5931 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005932 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005933 case NoLinkage:
5934 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 case InternalLinkage: return CXLinkage_Internal;
5936 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5937 case ExternalLinkage: return CXLinkage_External;
5938 };
5939
5940 return CXLinkage_Invalid;
5941}
5942} // end: extern "C"
5943
5944//===----------------------------------------------------------------------===//
5945// Operations for querying language of a cursor.
5946//===----------------------------------------------------------------------===//
5947
5948static CXLanguageKind getDeclLanguage(const Decl *D) {
5949 if (!D)
5950 return CXLanguage_C;
5951
5952 switch (D->getKind()) {
5953 default:
5954 break;
5955 case Decl::ImplicitParam:
5956 case Decl::ObjCAtDefsField:
5957 case Decl::ObjCCategory:
5958 case Decl::ObjCCategoryImpl:
5959 case Decl::ObjCCompatibleAlias:
5960 case Decl::ObjCImplementation:
5961 case Decl::ObjCInterface:
5962 case Decl::ObjCIvar:
5963 case Decl::ObjCMethod:
5964 case Decl::ObjCProperty:
5965 case Decl::ObjCPropertyImpl:
5966 case Decl::ObjCProtocol:
5967 return CXLanguage_ObjC;
5968 case Decl::CXXConstructor:
5969 case Decl::CXXConversion:
5970 case Decl::CXXDestructor:
5971 case Decl::CXXMethod:
5972 case Decl::CXXRecord:
5973 case Decl::ClassTemplate:
5974 case Decl::ClassTemplatePartialSpecialization:
5975 case Decl::ClassTemplateSpecialization:
5976 case Decl::Friend:
5977 case Decl::FriendTemplate:
5978 case Decl::FunctionTemplate:
5979 case Decl::LinkageSpec:
5980 case Decl::Namespace:
5981 case Decl::NamespaceAlias:
5982 case Decl::NonTypeTemplateParm:
5983 case Decl::StaticAssert:
5984 case Decl::TemplateTemplateParm:
5985 case Decl::TemplateTypeParm:
5986 case Decl::UnresolvedUsingTypename:
5987 case Decl::UnresolvedUsingValue:
5988 case Decl::Using:
5989 case Decl::UsingDirective:
5990 case Decl::UsingShadow:
5991 return CXLanguage_CPlusPlus;
5992 }
5993
5994 return CXLanguage_C;
5995}
5996
5997extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005998
5999static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6000 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6001 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006002
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006003 switch (D->getAvailability()) {
6004 case AR_Available:
6005 case AR_NotYetIntroduced:
6006 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006007 return getCursorAvailabilityForDecl(
6008 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006009 return CXAvailability_Available;
6010
6011 case AR_Deprecated:
6012 return CXAvailability_Deprecated;
6013
6014 case AR_Unavailable:
6015 return CXAvailability_NotAvailable;
6016 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006017
6018 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006019}
6020
Guy Benyei11169dd2012-12-18 14:30:41 +00006021enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6022 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006023 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6024 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006025
6026 return CXAvailability_Available;
6027}
6028
6029static CXVersion convertVersion(VersionTuple In) {
6030 CXVersion Out = { -1, -1, -1 };
6031 if (In.empty())
6032 return Out;
6033
6034 Out.Major = In.getMajor();
6035
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006036 Optional<unsigned> Minor = In.getMinor();
6037 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006038 Out.Minor = *Minor;
6039 else
6040 return Out;
6041
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006042 Optional<unsigned> Subminor = In.getSubminor();
6043 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006044 Out.Subminor = *Subminor;
6045
6046 return Out;
6047}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006048
6049static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6050 int *always_deprecated,
6051 CXString *deprecated_message,
6052 int *always_unavailable,
6053 CXString *unavailable_message,
6054 CXPlatformAvailability *availability,
6055 int availability_size) {
6056 bool HadAvailAttr = false;
6057 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006058 for (auto A : D->attrs()) {
6059 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006060 HadAvailAttr = true;
6061 if (always_deprecated)
6062 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006063 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006064 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006065 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006066 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006067 continue;
6068 }
6069
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006070 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071 HadAvailAttr = true;
6072 if (always_unavailable)
6073 *always_unavailable = 1;
6074 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006075 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006076 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6077 }
6078 continue;
6079 }
6080
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006081 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006082 HadAvailAttr = true;
6083 if (N < availability_size) {
6084 availability[N].Platform
6085 = cxstring::createDup(Avail->getPlatform()->getName());
6086 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6087 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6088 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6089 availability[N].Unavailable = Avail->getUnavailable();
6090 availability[N].Message = cxstring::createDup(Avail->getMessage());
6091 }
6092 ++N;
6093 }
6094 }
6095
6096 if (!HadAvailAttr)
6097 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6098 return getCursorPlatformAvailabilityForDecl(
6099 cast<Decl>(EnumConst->getDeclContext()),
6100 always_deprecated,
6101 deprecated_message,
6102 always_unavailable,
6103 unavailable_message,
6104 availability,
6105 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006106
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006107 return N;
6108}
6109
Guy Benyei11169dd2012-12-18 14:30:41 +00006110int clang_getCursorPlatformAvailability(CXCursor cursor,
6111 int *always_deprecated,
6112 CXString *deprecated_message,
6113 int *always_unavailable,
6114 CXString *unavailable_message,
6115 CXPlatformAvailability *availability,
6116 int availability_size) {
6117 if (always_deprecated)
6118 *always_deprecated = 0;
6119 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006120 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (always_unavailable)
6122 *always_unavailable = 0;
6123 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006124 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006125
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (!clang_isDeclaration(cursor.kind))
6127 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006128
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006129 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 if (!D)
6131 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006132
6133 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6134 deprecated_message,
6135 always_unavailable,
6136 unavailable_message,
6137 availability,
6138 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006139}
6140
6141void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6142 clang_disposeString(availability->Platform);
6143 clang_disposeString(availability->Message);
6144}
6145
6146CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6147 if (clang_isDeclaration(cursor.kind))
6148 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6149
6150 return CXLanguage_Invalid;
6151}
6152
6153 /// \brief If the given cursor is the "templated" declaration
6154 /// descibing a class or function template, return the class or
6155 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006156static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006158 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006159
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006160 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6162 return FunTmpl;
6163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006164 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6166 return ClassTmpl;
6167
6168 return D;
6169}
6170
6171CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6172 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006173 if (const Decl *D = getCursorDecl(cursor)) {
6174 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 if (!DC)
6176 return clang_getNullCursor();
6177
6178 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6179 getCursorTU(cursor));
6180 }
6181 }
6182
6183 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006184 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 return MakeCXCursor(D, getCursorTU(cursor));
6186 }
6187
6188 return clang_getNullCursor();
6189}
6190
6191CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6192 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006193 if (const Decl *D = getCursorDecl(cursor)) {
6194 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 if (!DC)
6196 return clang_getNullCursor();
6197
6198 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6199 getCursorTU(cursor));
6200 }
6201 }
6202
6203 // FIXME: Note that we can't easily compute the lexical context of a
6204 // statement or expression, so we return nothing.
6205 return clang_getNullCursor();
6206}
6207
6208CXFile clang_getIncludedFile(CXCursor cursor) {
6209 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006210 return nullptr;
6211
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006212 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006213 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006214}
6215
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006216unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6217 if (C.kind != CXCursor_ObjCPropertyDecl)
6218 return CXObjCPropertyAttr_noattr;
6219
6220 unsigned Result = CXObjCPropertyAttr_noattr;
6221 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6222 ObjCPropertyDecl::PropertyAttributeKind Attr =
6223 PD->getPropertyAttributesAsWritten();
6224
6225#define SET_CXOBJCPROP_ATTR(A) \
6226 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6227 Result |= CXObjCPropertyAttr_##A
6228 SET_CXOBJCPROP_ATTR(readonly);
6229 SET_CXOBJCPROP_ATTR(getter);
6230 SET_CXOBJCPROP_ATTR(assign);
6231 SET_CXOBJCPROP_ATTR(readwrite);
6232 SET_CXOBJCPROP_ATTR(retain);
6233 SET_CXOBJCPROP_ATTR(copy);
6234 SET_CXOBJCPROP_ATTR(nonatomic);
6235 SET_CXOBJCPROP_ATTR(setter);
6236 SET_CXOBJCPROP_ATTR(atomic);
6237 SET_CXOBJCPROP_ATTR(weak);
6238 SET_CXOBJCPROP_ATTR(strong);
6239 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6240#undef SET_CXOBJCPROP_ATTR
6241
6242 return Result;
6243}
6244
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006245unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6246 if (!clang_isDeclaration(C.kind))
6247 return CXObjCDeclQualifier_None;
6248
6249 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6250 const Decl *D = getCursorDecl(C);
6251 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6252 QT = MD->getObjCDeclQualifier();
6253 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6254 QT = PD->getObjCDeclQualifier();
6255 if (QT == Decl::OBJC_TQ_None)
6256 return CXObjCDeclQualifier_None;
6257
6258 unsigned Result = CXObjCDeclQualifier_None;
6259 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6260 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6261 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6262 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6263 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6264 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6265
6266 return Result;
6267}
6268
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006269unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6270 if (!clang_isDeclaration(C.kind))
6271 return 0;
6272
6273 const Decl *D = getCursorDecl(C);
6274 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6275 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6276 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6277 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6278
6279 return 0;
6280}
6281
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006282unsigned clang_Cursor_isVariadic(CXCursor C) {
6283 if (!clang_isDeclaration(C.kind))
6284 return 0;
6285
6286 const Decl *D = getCursorDecl(C);
6287 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6288 return FD->isVariadic();
6289 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6290 return MD->isVariadic();
6291
6292 return 0;
6293}
6294
Guy Benyei11169dd2012-12-18 14:30:41 +00006295CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6296 if (!clang_isDeclaration(C.kind))
6297 return clang_getNullRange();
6298
6299 const Decl *D = getCursorDecl(C);
6300 ASTContext &Context = getCursorContext(C);
6301 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6302 if (!RC)
6303 return clang_getNullRange();
6304
6305 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6306}
6307
6308CXString clang_Cursor_getRawCommentText(CXCursor C) {
6309 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006310 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
6312 const Decl *D = getCursorDecl(C);
6313 ASTContext &Context = getCursorContext(C);
6314 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6315 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6316 StringRef();
6317
6318 // Don't duplicate the string because RawText points directly into source
6319 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006320 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006321}
6322
6323CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6324 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006325 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006326
6327 const Decl *D = getCursorDecl(C);
6328 const ASTContext &Context = getCursorContext(C);
6329 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6330
6331 if (RC) {
6332 StringRef BriefText = RC->getBriefText(Context);
6333
6334 // Don't duplicate the string because RawComment ensures that this memory
6335 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006336 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 }
6338
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006339 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006340}
6341
Guy Benyei11169dd2012-12-18 14:30:41 +00006342CXModule clang_Cursor_getModule(CXCursor C) {
6343 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006344 if (const ImportDecl *ImportD =
6345 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 return ImportD->getImportedModule();
6347 }
6348
Craig Topper69186e72014-06-08 08:38:04 +00006349 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006350}
6351
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006352CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6353 if (isNotUsableTU(TU)) {
6354 LOG_BAD_TU(TU);
6355 return nullptr;
6356 }
6357 if (!File)
6358 return nullptr;
6359 FileEntry *FE = static_cast<FileEntry *>(File);
6360
6361 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6362 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6363 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6364
6365 if (Module *Mod = Header.getModule()) {
6366 if (Header.getRole() != ModuleMap::ExcludedHeader)
6367 return Mod;
6368 }
6369 return nullptr;
6370}
6371
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006372CXFile clang_Module_getASTFile(CXModule CXMod) {
6373 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006374 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006375 Module *Mod = static_cast<Module*>(CXMod);
6376 return const_cast<FileEntry *>(Mod->getASTFile());
6377}
6378
Guy Benyei11169dd2012-12-18 14:30:41 +00006379CXModule clang_Module_getParent(CXModule CXMod) {
6380 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006381 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 Module *Mod = static_cast<Module*>(CXMod);
6383 return Mod->Parent;
6384}
6385
6386CXString clang_Module_getName(CXModule CXMod) {
6387 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006388 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006389 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006390 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006391}
6392
6393CXString clang_Module_getFullName(CXModule CXMod) {
6394 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006395 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006397 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006398}
6399
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006400int clang_Module_isSystem(CXModule CXMod) {
6401 if (!CXMod)
6402 return 0;
6403 Module *Mod = static_cast<Module*>(CXMod);
6404 return Mod->IsSystem;
6405}
6406
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006407unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6408 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006409 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006410 LOG_BAD_TU(TU);
6411 return 0;
6412 }
6413 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 return 0;
6415 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006416 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6417 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6418 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006419}
6420
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006421CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6422 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006423 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006424 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006425 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006426 }
6427 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006428 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006430 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006431
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006432 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6433 if (Index < TopHeaders.size())
6434 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006435
Craig Topper69186e72014-06-08 08:38:04 +00006436 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006437}
6438
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// C++ AST instrospection.
6443//===----------------------------------------------------------------------===//
6444
6445extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006446unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6447 if (!clang_isDeclaration(C.kind))
6448 return 0;
6449
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006450 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006451 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006452 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006453 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6454}
6455
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006456unsigned clang_CXXMethod_isConst(CXCursor C) {
6457 if (!clang_isDeclaration(C.kind))
6458 return 0;
6459
6460 const Decl *D = cxcursor::getCursorDecl(C);
6461 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006462 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006463 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6464}
6465
Guy Benyei11169dd2012-12-18 14:30:41 +00006466unsigned clang_CXXMethod_isStatic(CXCursor C) {
6467 if (!clang_isDeclaration(C.kind))
6468 return 0;
6469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006470 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006471 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006472 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 return (Method && Method->isStatic()) ? 1 : 0;
6474}
6475
6476unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6477 if (!clang_isDeclaration(C.kind))
6478 return 0;
6479
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006480 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006481 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006482 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006483 return (Method && Method->isVirtual()) ? 1 : 0;
6484}
6485} // end: extern "C"
6486
6487//===----------------------------------------------------------------------===//
6488// Attribute introspection.
6489//===----------------------------------------------------------------------===//
6490
6491extern "C" {
6492CXType clang_getIBOutletCollectionType(CXCursor C) {
6493 if (C.kind != CXCursor_IBOutletCollectionAttr)
6494 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6495
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006496 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006497 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6498
6499 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6500}
6501} // end: extern "C"
6502
6503//===----------------------------------------------------------------------===//
6504// Inspecting memory usage.
6505//===----------------------------------------------------------------------===//
6506
6507typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6508
6509static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6510 enum CXTUResourceUsageKind k,
6511 unsigned long amount) {
6512 CXTUResourceUsageEntry entry = { k, amount };
6513 entries.push_back(entry);
6514}
6515
6516extern "C" {
6517
6518const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6519 const char *str = "";
6520 switch (kind) {
6521 case CXTUResourceUsage_AST:
6522 str = "ASTContext: expressions, declarations, and types";
6523 break;
6524 case CXTUResourceUsage_Identifiers:
6525 str = "ASTContext: identifiers";
6526 break;
6527 case CXTUResourceUsage_Selectors:
6528 str = "ASTContext: selectors";
6529 break;
6530 case CXTUResourceUsage_GlobalCompletionResults:
6531 str = "Code completion: cached global results";
6532 break;
6533 case CXTUResourceUsage_SourceManagerContentCache:
6534 str = "SourceManager: content cache allocator";
6535 break;
6536 case CXTUResourceUsage_AST_SideTables:
6537 str = "ASTContext: side tables";
6538 break;
6539 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6540 str = "SourceManager: malloc'ed memory buffers";
6541 break;
6542 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6543 str = "SourceManager: mmap'ed memory buffers";
6544 break;
6545 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6546 str = "ExternalASTSource: malloc'ed memory buffers";
6547 break;
6548 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6549 str = "ExternalASTSource: mmap'ed memory buffers";
6550 break;
6551 case CXTUResourceUsage_Preprocessor:
6552 str = "Preprocessor: malloc'ed memory";
6553 break;
6554 case CXTUResourceUsage_PreprocessingRecord:
6555 str = "Preprocessor: PreprocessingRecord";
6556 break;
6557 case CXTUResourceUsage_SourceManager_DataStructures:
6558 str = "SourceManager: data structures and tables";
6559 break;
6560 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6561 str = "Preprocessor: header search tables";
6562 break;
6563 }
6564 return str;
6565}
6566
6567CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006568 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006569 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006570 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 return usage;
6572 }
6573
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006574 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006575 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006576 ASTContext &astContext = astUnit->getASTContext();
6577
6578 // How much memory is used by AST nodes and types?
6579 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6580 (unsigned long) astContext.getASTAllocatedMemory());
6581
6582 // How much memory is used by identifiers?
6583 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6584 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6585
6586 // How much memory is used for selectors?
6587 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6588 (unsigned long) astContext.Selectors.getTotalMemory());
6589
6590 // How much memory is used by ASTContext's side tables?
6591 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6592 (unsigned long) astContext.getSideTableAllocatedMemory());
6593
6594 // How much memory is used for caching global code completion results?
6595 unsigned long completionBytes = 0;
6596 if (GlobalCodeCompletionAllocator *completionAllocator =
6597 astUnit->getCachedCompletionAllocator().getPtr()) {
6598 completionBytes = completionAllocator->getTotalMemory();
6599 }
6600 createCXTUResourceUsageEntry(*entries,
6601 CXTUResourceUsage_GlobalCompletionResults,
6602 completionBytes);
6603
6604 // How much memory is being used by SourceManager's content cache?
6605 createCXTUResourceUsageEntry(*entries,
6606 CXTUResourceUsage_SourceManagerContentCache,
6607 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6608
6609 // How much memory is being used by the MemoryBuffer's in SourceManager?
6610 const SourceManager::MemoryBufferSizes &srcBufs =
6611 astUnit->getSourceManager().getMemoryBufferSizes();
6612
6613 createCXTUResourceUsageEntry(*entries,
6614 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6615 (unsigned long) srcBufs.malloc_bytes);
6616 createCXTUResourceUsageEntry(*entries,
6617 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6618 (unsigned long) srcBufs.mmap_bytes);
6619 createCXTUResourceUsageEntry(*entries,
6620 CXTUResourceUsage_SourceManager_DataStructures,
6621 (unsigned long) astContext.getSourceManager()
6622 .getDataStructureSizes());
6623
6624 // How much memory is being used by the ExternalASTSource?
6625 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6626 const ExternalASTSource::MemoryBufferSizes &sizes =
6627 esrc->getMemoryBufferSizes();
6628
6629 createCXTUResourceUsageEntry(*entries,
6630 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6631 (unsigned long) sizes.malloc_bytes);
6632 createCXTUResourceUsageEntry(*entries,
6633 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6634 (unsigned long) sizes.mmap_bytes);
6635 }
6636
6637 // How much memory is being used by the Preprocessor?
6638 Preprocessor &pp = astUnit->getPreprocessor();
6639 createCXTUResourceUsageEntry(*entries,
6640 CXTUResourceUsage_Preprocessor,
6641 pp.getTotalMemory());
6642
6643 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6644 createCXTUResourceUsageEntry(*entries,
6645 CXTUResourceUsage_PreprocessingRecord,
6646 pRec->getTotalMemory());
6647 }
6648
6649 createCXTUResourceUsageEntry(*entries,
6650 CXTUResourceUsage_Preprocessor_HeaderSearch,
6651 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006652
Guy Benyei11169dd2012-12-18 14:30:41 +00006653 CXTUResourceUsage usage = { (void*) entries.get(),
6654 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006655 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006656 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 return usage;
6658}
6659
6660void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6661 if (usage.data)
6662 delete (MemUsageEntries*) usage.data;
6663}
6664
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006665CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6666 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006667 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006668 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006669
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006670 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006671 LOG_BAD_TU(TU);
6672 return skipped;
6673 }
6674
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006675 if (!file)
6676 return skipped;
6677
6678 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6679 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6680 if (!ppRec)
6681 return skipped;
6682
6683 ASTContext &Ctx = astUnit->getASTContext();
6684 SourceManager &sm = Ctx.getSourceManager();
6685 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6686 FileID wantedFileID = sm.translateFile(fileEntry);
6687
6688 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6689 std::vector<SourceRange> wantedRanges;
6690 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6691 i != ei; ++i) {
6692 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6693 wantedRanges.push_back(*i);
6694 }
6695
6696 skipped->count = wantedRanges.size();
6697 skipped->ranges = new CXSourceRange[skipped->count];
6698 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6699 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6700
6701 return skipped;
6702}
6703
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006704void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6705 if (ranges) {
6706 delete[] ranges->ranges;
6707 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006708 }
6709}
6710
Guy Benyei11169dd2012-12-18 14:30:41 +00006711} // end extern "C"
6712
6713void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6714 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6715 for (unsigned I = 0; I != Usage.numEntries; ++I)
6716 fprintf(stderr, " %s: %lu\n",
6717 clang_getTUResourceUsageName(Usage.entries[I].kind),
6718 Usage.entries[I].amount);
6719
6720 clang_disposeCXTUResourceUsage(Usage);
6721}
6722
6723//===----------------------------------------------------------------------===//
6724// Misc. utility functions.
6725//===----------------------------------------------------------------------===//
6726
6727/// Default to using an 8 MB stack size on "safety" threads.
6728static unsigned SafetyStackThreadSize = 8 << 20;
6729
6730namespace clang {
6731
6732bool RunSafely(llvm::CrashRecoveryContext &CRC,
6733 void (*Fn)(void*), void *UserData,
6734 unsigned Size) {
6735 if (!Size)
6736 Size = GetSafetyThreadStackSize();
6737 if (Size)
6738 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6739 return CRC.RunSafely(Fn, UserData);
6740}
6741
6742unsigned GetSafetyThreadStackSize() {
6743 return SafetyStackThreadSize;
6744}
6745
6746void SetSafetyThreadStackSize(unsigned Value) {
6747 SafetyStackThreadSize = Value;
6748}
6749
6750}
6751
6752void clang::setThreadBackgroundPriority() {
6753 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6754 return;
6755
6756 // FIXME: Move to llvm/Support and make it cross-platform.
6757#ifdef __APPLE__
6758 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6759#endif
6760}
6761
6762void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6763 if (!Unit)
6764 return;
6765
6766 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6767 DEnd = Unit->stored_diag_end();
6768 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006769 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006770 CXString Msg = clang_formatDiagnostic(&Diag,
6771 clang_defaultDiagnosticDisplayOptions());
6772 fprintf(stderr, "%s\n", clang_getCString(Msg));
6773 clang_disposeString(Msg);
6774 }
6775#ifdef LLVM_ON_WIN32
6776 // On Windows, force a flush, since there may be multiple copies of
6777 // stderr and stdout in the file system, all with different buffers
6778 // but writing to the same device.
6779 fflush(stderr);
6780#endif
6781}
6782
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6784 SourceLocation MacroDefLoc,
6785 CXTranslationUnit TU){
6786 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006787 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006788 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006789 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006790
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006791 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006792 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006793 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006794 if (MD) {
6795 for (MacroDirective::DefInfo
6796 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6797 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6798 return Def.getMacroInfo();
6799 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006800 }
6801
Craig Topper69186e72014-06-08 08:38:04 +00006802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006803}
6804
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006805const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6806 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006807 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006808 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006809 const IdentifierInfo *II = MacroDef->getName();
6810 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006811 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006812
6813 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6814}
6815
6816MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6817 const Token &Tok,
6818 CXTranslationUnit TU) {
6819 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006820 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006823
6824 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006825 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006826 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6827 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006828 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006829
6830 // Check that the token is inside the definition and not its argument list.
6831 SourceManager &SM = Unit->getSourceManager();
6832 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836
6837 Preprocessor &PP = Unit->getPreprocessor();
6838 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6839 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006841
Alp Toker2d57cea2014-05-17 04:53:25 +00006842 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006843 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006844 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006845
6846 // Check that the identifier is not one of the macro arguments.
6847 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006848 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006849
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006850 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6851 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006852 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006853
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006854 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855}
6856
6857MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6858 SourceLocation Loc,
6859 CXTranslationUnit TU) {
6860 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006862
6863 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006864 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006865 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866 Preprocessor &PP = Unit->getPreprocessor();
6867 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006869 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6870 Token Tok;
6871 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873
6874 return checkForMacroInMacroDefinition(MI, Tok, TU);
6875}
6876
Guy Benyei11169dd2012-12-18 14:30:41 +00006877extern "C" {
6878
6879CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006880 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006881}
6882
6883} // end: extern "C"
6884
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006885Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6886 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006887 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006888 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006889 if (Unit->isMainFileAST())
6890 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006891 return *this;
6892 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006893 } else {
6894 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006895 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006896 return *this;
6897}
6898
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006899Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6900 *this << FE->getName();
6901 return *this;
6902}
6903
6904Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6905 CXString cursorName = clang_getCursorDisplayName(cursor);
6906 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6907 clang_disposeString(cursorName);
6908 return *this;
6909}
6910
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006911Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6912 CXFile File;
6913 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006914 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006915 CXString FileName = clang_getFileName(File);
6916 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6917 clang_disposeString(FileName);
6918 return *this;
6919}
6920
6921Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6922 CXSourceLocation BLoc = clang_getRangeStart(range);
6923 CXSourceLocation ELoc = clang_getRangeEnd(range);
6924
6925 CXFile BFile;
6926 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006927 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006928
6929 CXFile EFile;
6930 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006931 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006932
6933 CXString BFileName = clang_getFileName(BFile);
6934 if (BFile == EFile) {
6935 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6936 BLine, BColumn, ELine, EColumn);
6937 } else {
6938 CXString EFileName = clang_getFileName(EFile);
6939 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6940 BLine, BColumn)
6941 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6942 ELine, EColumn);
6943 clang_disposeString(EFileName);
6944 }
6945 clang_disposeString(BFileName);
6946 return *this;
6947}
6948
6949Logger &cxindex::Logger::operator<<(CXString Str) {
6950 *this << clang_getCString(Str);
6951 return *this;
6952}
6953
6954Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6955 LogOS << Fmt;
6956 return *this;
6957}
6958
6959cxindex::Logger::~Logger() {
6960 LogOS.flush();
6961
6962 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6963
6964 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6965
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006966 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006967 OS << "[libclang:" << Name << ':';
6968
6969 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006970#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006971 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6972 OS << tid << ':';
6973#endif
6974
6975 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6976 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6977 OS << Msg.str() << '\n';
6978
6979 if (Trace) {
6980 llvm::sys::PrintStackTrace(stderr);
6981 OS << "--------------------------------------------------\n";
6982 }
6983}