blob: 78144d50e50762bfbab20fe812eda09c46dcc821 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Program.h"
49#include "llvm/Support/SaveAndRestore.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/Threading.h"
52#include "llvm/Support/Timer.h"
53#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000054
Alp Toker1d257e12014-06-04 03:28:55 +000055#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000056#include <pthread.h>
57#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000058
59using namespace clang;
60using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000061using namespace clang::cxtu;
62using namespace clang::cxindex;
63
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000064CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
65 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000066 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000067 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000068 CXTranslationUnit D = new CXTranslationUnitImpl();
69 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000070 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000071 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000072 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000074 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000075 return D;
76}
77
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078bool cxtu::isASTReadError(ASTUnit *AU) {
79 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
80 DEnd = AU->stored_diag_end();
81 D != DEnd; ++D) {
82 if (D->getLevel() >= DiagnosticsEngine::Error &&
83 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
84 diag::DiagCat_AST_Deserialization_Issue)
85 return true;
86 }
87 return false;
88}
89
Guy Benyei11169dd2012-12-18 14:30:41 +000090cxtu::CXTUOwner::~CXTUOwner() {
91 if (TU)
92 clang_disposeTranslationUnit(TU);
93}
94
95/// \brief Compare two source ranges to determine their relative position in
96/// the translation unit.
97static RangeComparisonResult RangeCompare(SourceManager &SM,
98 SourceRange R1,
99 SourceRange R2) {
100 assert(R1.isValid() && "First range is invalid?");
101 assert(R2.isValid() && "Second range is invalid?");
102 if (R1.getEnd() != R2.getBegin() &&
103 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
104 return RangeBefore;
105 if (R2.getEnd() != R1.getBegin() &&
106 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Determine if a source location falls within, before, or after a
112/// a given source range.
113static RangeComparisonResult LocationCompare(SourceManager &SM,
114 SourceLocation L, SourceRange R) {
115 assert(R.isValid() && "First range is invalid?");
116 assert(L.isValid() && "Second range is invalid?");
117 if (L == R.getBegin() || L == R.getEnd())
118 return RangeOverlap;
119 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
120 return RangeBefore;
121 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
122 return RangeAfter;
123 return RangeOverlap;
124}
125
126/// \brief Translate a Clang source range into a CIndex source range.
127///
128/// Clang internally represents ranges where the end location points to the
129/// start of the token at the end. However, for external clients it is more
130/// useful to have a CXSourceRange be a proper half-open interval. This routine
131/// does the appropriate translation.
132CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
133 const LangOptions &LangOpts,
134 const CharSourceRange &R) {
135 // We want the last character in this location, so we will adjust the
136 // location accordingly.
137 SourceLocation EndLoc = R.getEnd();
138 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
139 EndLoc = SM.getExpansionRange(EndLoc).second;
140 if (R.isTokenRange() && !EndLoc.isInvalid()) {
141 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
142 SM, LangOpts);
143 EndLoc = EndLoc.getLocWithOffset(Length);
144 }
145
Bill Wendlingeade3622013-01-23 08:25:41 +0000146 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000147 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000148 R.getBegin().getRawEncoding(),
149 EndLoc.getRawEncoding()
150 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 return Result;
152}
153
154//===----------------------------------------------------------------------===//
155// Cursor visitor.
156//===----------------------------------------------------------------------===//
157
158static SourceRange getRawCursorExtent(CXCursor C);
159static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
160
161
162RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
163 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
164}
165
166/// \brief Visit the given cursor and, if requested by the visitor,
167/// its children.
168///
169/// \param Cursor the cursor to visit.
170///
171/// \param CheckedRegionOfInterest if true, then the caller already checked
172/// that this cursor is within the region of interest.
173///
174/// \returns true if the visitation should be aborted, false if it
175/// should continue.
176bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
177 if (clang_isInvalid(Cursor.kind))
178 return false;
179
180 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000181 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000182 if (!D) {
183 assert(0 && "Invalid declaration cursor");
184 return true; // abort.
185 }
186
187 // Ignore implicit declarations, unless it's an objc method because
188 // currently we should report implicit methods for properties when indexing.
189 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
190 return false;
191 }
192
193 // If we have a range of interest, and this cursor doesn't intersect with it,
194 // we're done.
195 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
196 SourceRange Range = getRawCursorExtent(Cursor);
197 if (Range.isInvalid() || CompareRegionOfInterest(Range))
198 return false;
199 }
200
201 switch (Visitor(Cursor, Parent, ClientData)) {
202 case CXChildVisit_Break:
203 return true;
204
205 case CXChildVisit_Continue:
206 return false;
207
208 case CXChildVisit_Recurse: {
209 bool ret = VisitChildren(Cursor);
210 if (PostChildrenVisitor)
211 if (PostChildrenVisitor(Cursor, ClientData))
212 return true;
213 return ret;
214 }
215 }
216
217 llvm_unreachable("Invalid CXChildVisitResult!");
218}
219
220static bool visitPreprocessedEntitiesInRange(SourceRange R,
221 PreprocessingRecord &PPRec,
222 CursorVisitor &Visitor) {
223 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
224 FileID FID;
225
226 if (!Visitor.shouldVisitIncludedEntities()) {
227 // If the begin/end of the range lie in the same FileID, do the optimization
228 // where we skip preprocessed entities that do not come from the same FileID.
229 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
230 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
231 FID = FileID();
232 }
233
234 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
235 Entities = PPRec.getPreprocessedEntitiesInRange(R);
236 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
237 PPRec, FID);
238}
239
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000240bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000242 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000244 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 SourceManager &SM = Unit->getSourceManager();
246
247 std::pair<FileID, unsigned>
248 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
249 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
250
251 if (End.first != Begin.first) {
252 // If the end does not reside in the same file, try to recover by
253 // picking the end of the file of begin location.
254 End.first = Begin.first;
255 End.second = SM.getFileIDSize(Begin.first);
256 }
257
258 assert(Begin.first == End.first);
259 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000260 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000261
262 FileID File = Begin.first;
263 unsigned Offset = Begin.second;
264 unsigned Length = End.second - Begin.second;
265
266 if (!VisitDeclsOnly && !VisitPreprocessorLast)
267 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 if (visitDeclsFromFileRegion(File, Offset, Length))
271 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000272
273 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return visitPreprocessedEntitiesInRegion();
275
276 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000277}
278
279static bool isInLexicalContext(Decl *D, DeclContext *DC) {
280 if (!DC)
281 return false;
282
283 for (DeclContext *DeclDC = D->getLexicalDeclContext();
284 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
285 if (DeclDC == DC)
286 return true;
287 }
288 return false;
289}
290
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000292 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000293 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000294 SourceManager &SM = Unit->getSourceManager();
295 SourceRange Range = RegionOfInterest;
296
297 SmallVector<Decl *, 16> Decls;
298 Unit->findFileRegionDecls(File, Offset, Length, Decls);
299
300 // If we didn't find any file level decls for the file, try looking at the
301 // file that it was included from.
302 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
303 bool Invalid = false;
304 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
305 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000306 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000307
308 SourceLocation Outer;
309 if (SLEntry.isFile())
310 Outer = SLEntry.getFile().getIncludeLoc();
311 else
312 Outer = SLEntry.getExpansion().getExpansionLocStart();
313 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000316 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000317 Length = 0;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
319 }
320
321 assert(!Decls.empty());
322
323 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000324 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000325 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
326 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Decl *D = *DIt;
328 if (D->getSourceRange().isInvalid())
329 continue;
330
331 if (isInLexicalContext(D, CurDC))
332 continue;
333
334 CurDC = dyn_cast<DeclContext>(D);
335
336 if (TagDecl *TD = dyn_cast<TagDecl>(D))
337 if (!TD->isFreeStanding())
338 continue;
339
340 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
341 if (CompRes == RangeBefore)
342 continue;
343 if (CompRes == RangeAfter)
344 break;
345
346 assert(CompRes == RangeOverlap);
347 VisitedAtLeastOnce = true;
348
349 if (isa<ObjCContainerDecl>(D)) {
350 FileDI_current = &DIt;
351 FileDE_current = DE;
352 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000353 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000354 }
355
356 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000357 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000358 }
359
360 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362
363 // No Decls overlapped with the range. Move up the lexical context until there
364 // is a context that contains the range or we reach the translation unit
365 // level.
366 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
367 : (*(DIt-1))->getLexicalDeclContext();
368
369 while (DC && !DC->isTranslationUnit()) {
370 Decl *D = cast<Decl>(DC);
371 SourceRange CurDeclRange = D->getSourceRange();
372 if (CurDeclRange.isInvalid())
373 break;
374
375 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000376 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
377 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000378 }
379
380 DC = D->getLexicalDeclContext();
381 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382
383 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000384}
385
386bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
387 if (!AU->getPreprocessor().getPreprocessingRecord())
388 return false;
389
390 PreprocessingRecord &PPRec
391 = *AU->getPreprocessor().getPreprocessingRecord();
392 SourceManager &SM = AU->getSourceManager();
393
394 if (RegionOfInterest.isValid()) {
395 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
396 SourceLocation B = MappedRange.getBegin();
397 SourceLocation E = MappedRange.getEnd();
398
399 if (AU->isInPreambleFileID(B)) {
400 if (SM.isLoadedSourceLocation(E))
401 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
402 PPRec, *this);
403
404 // Beginning of range lies in the preamble but it also extends beyond
405 // it into the main file. Split the range into 2 parts, one covering
406 // the preamble and another covering the main file. This allows subsequent
407 // calls to visitPreprocessedEntitiesInRange to accept a source range that
408 // lies in the same FileID, allowing it to skip preprocessed entities that
409 // do not come from the same FileID.
410 bool breaked =
411 visitPreprocessedEntitiesInRange(
412 SourceRange(B, AU->getEndOfPreambleFileID()),
413 PPRec, *this);
414 if (breaked) return true;
415 return visitPreprocessedEntitiesInRange(
416 SourceRange(AU->getStartOfMainFileID(), E),
417 PPRec, *this);
418 }
419
420 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
421 }
422
423 bool OnlyLocalDecls
424 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
425
426 if (OnlyLocalDecls)
427 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
428 PPRec);
429
430 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
431}
432
433template<typename InputIterator>
434bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
435 InputIterator Last,
436 PreprocessingRecord &PPRec,
437 FileID FID) {
438 for (; First != Last; ++First) {
439 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
440 continue;
441
442 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000443 if (!PPE)
444 continue;
445
Guy Benyei11169dd2012-12-18 14:30:41 +0000446 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
447 if (Visit(MakeMacroExpansionCursor(ME, TU)))
448 return true;
449
450 continue;
451 }
452
453 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
454 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
455 return true;
456
457 continue;
458 }
459
460 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
461 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
462 return true;
463
464 continue;
465 }
466 }
467
468 return false;
469}
470
471/// \brief Visit the children of the given cursor.
472///
473/// \returns true if the visitation should be aborted, false if it
474/// should continue.
475bool CursorVisitor::VisitChildren(CXCursor Cursor) {
476 if (clang_isReference(Cursor.kind) &&
477 Cursor.kind != CXCursor_CXXBaseSpecifier) {
478 // By definition, references have no children.
479 return false;
480 }
481
482 // Set the Parent field to Cursor, then back to its old value once we're
483 // done.
484 SetParentRAII SetParent(Parent, StmtParent, Cursor);
485
486 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000487 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 if (!D)
489 return false;
490
491 return VisitAttributes(D) || Visit(D);
492 }
493
494 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000495 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 return Visit(S);
497
498 return false;
499 }
500
501 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000502 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000503 return Visit(E);
504
505 return false;
506 }
507
508 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000509 CXTranslationUnit TU = getCursorTU(Cursor);
510 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000511
512 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
513 for (unsigned I = 0; I != 2; ++I) {
514 if (VisitOrder[I]) {
515 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
516 RegionOfInterest.isInvalid()) {
517 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
518 TLEnd = CXXUnit->top_level_end();
519 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000521 return true;
522 }
523 } else if (VisitDeclContext(
524 CXXUnit->getASTContext().getTranslationUnitDecl()))
525 return true;
526 continue;
527 }
528
529 // Walk the preprocessing record.
530 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
531 visitPreprocessedEntitiesInRegion();
532 }
533
534 return false;
535 }
536
537 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000538 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000539 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
540 return Visit(BaseTSInfo->getTypeLoc());
541 }
542 }
543 }
544
545 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000546 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000548 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000549 return Visit(cxcursor::MakeCursorObjCClassRef(
550 ObjT->getInterface(),
551 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 }
553
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000554 // If pointing inside a macro definition, check if the token is an identifier
555 // that was ever defined as a macro. In such a case, create a "pseudo" macro
556 // expansion cursor for that token.
557 SourceLocation BeginLoc = RegionOfInterest.getBegin();
558 if (Cursor.kind == CXCursor_MacroDefinition &&
559 BeginLoc == RegionOfInterest.getEnd()) {
560 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000561 const MacroInfo *MI =
562 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 if (MacroDefinition *MacroDef =
564 checkForMacroInMacroDefinition(MI, Loc, TU))
565 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
566 }
567
Guy Benyei11169dd2012-12-18 14:30:41 +0000568 // Nothing to visit at the moment.
569 return false;
570}
571
572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
573 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
574 if (Visit(TSInfo->getTypeLoc()))
575 return true;
576
577 if (Stmt *Body = B->getBody())
578 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
579
580 return false;
581}
582
Ted Kremenek03325582013-02-21 01:29:01 +0000583Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000584 if (RegionOfInterest.isValid()) {
585 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
586 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000587 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 switch (CompareRegionOfInterest(Range)) {
590 case RangeBefore:
591 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 case RangeAfter:
595 // This declaration comes after the region of interest; we're done.
596 return false;
597
598 case RangeOverlap:
599 // This declaration overlaps the region of interest; visit it.
600 break;
601 }
602 }
603 return true;
604}
605
606bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
607 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
608
609 // FIXME: Eventually remove. This part of a hack to support proper
610 // iteration over all Decls contained lexically within an ObjC container.
611 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
612 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
613
614 for ( ; I != E; ++I) {
615 Decl *D = *I;
616 if (D->getLexicalDeclContext() != DC)
617 continue;
618 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
619
620 // Ignore synthesized ivars here, otherwise if we have something like:
621 // @synthesize prop = _prop;
622 // and '_prop' is not declared, we will encounter a '_prop' ivar before
623 // encountering the 'prop' synthesize declaration and we will think that
624 // we passed the region-of-interest.
625 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
626 if (ivarD->getSynthesize())
627 continue;
628 }
629
630 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
631 // declarations is a mismatch with the compiler semantics.
632 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
633 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
634 if (!ID->isThisDeclarationADefinition())
635 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
636
637 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
638 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
639 if (!PD->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
641 }
642
Ted Kremenek03325582013-02-21 01:29:01 +0000643 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000644 if (!V.hasValue())
645 continue;
646 if (!V.getValue())
647 return false;
648 if (Visit(Cursor, true))
649 return true;
650 }
651 return false;
652}
653
654bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
655 llvm_unreachable("Translation units are visited directly by Visit()");
656}
657
658bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
659 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
660 return Visit(TSInfo->getTypeLoc());
661
662 return false;
663}
664
665bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
666 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
667 return Visit(TSInfo->getTypeLoc());
668
669 return false;
670}
671
672bool CursorVisitor::VisitTagDecl(TagDecl *D) {
673 return VisitDeclContext(D);
674}
675
676bool CursorVisitor::VisitClassTemplateSpecializationDecl(
677 ClassTemplateSpecializationDecl *D) {
678 bool ShouldVisitBody = false;
679 switch (D->getSpecializationKind()) {
680 case TSK_Undeclared:
681 case TSK_ImplicitInstantiation:
682 // Nothing to visit
683 return false;
684
685 case TSK_ExplicitInstantiationDeclaration:
686 case TSK_ExplicitInstantiationDefinition:
687 break;
688
689 case TSK_ExplicitSpecialization:
690 ShouldVisitBody = true;
691 break;
692 }
693
694 // Visit the template arguments used in the specialization.
695 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
696 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000697 if (TemplateSpecializationTypeLoc TSTLoc =
698 TL.getAs<TemplateSpecializationTypeLoc>()) {
699 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
700 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000701 return true;
702 }
703 }
704
705 if (ShouldVisitBody && VisitCXXRecordDecl(D))
706 return true;
707
708 return false;
709}
710
711bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
712 ClassTemplatePartialSpecializationDecl *D) {
713 // FIXME: Visit the "outer" template parameter lists on the TagDecl
714 // before visiting these template parameters.
715 if (VisitTemplateParameters(D->getTemplateParameters()))
716 return true;
717
718 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000719 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
720 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
721 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000722 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
723 return true;
724
725 return VisitCXXRecordDecl(D);
726}
727
728bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
729 // Visit the default argument.
730 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
731 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
732 if (Visit(DefArg->getTypeLoc()))
733 return true;
734
735 return false;
736}
737
738bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
739 if (Expr *Init = D->getInitExpr())
740 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
741 return false;
742}
743
744bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000745 unsigned NumParamList = DD->getNumTemplateParameterLists();
746 for (unsigned i = 0; i < NumParamList; i++) {
747 TemplateParameterList* Params = DD->getTemplateParameterList(i);
748 if (VisitTemplateParameters(Params))
749 return true;
750 }
751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
753 if (Visit(TSInfo->getTypeLoc()))
754 return true;
755
756 // Visit the nested-name-specifier, if present.
757 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
758 if (VisitNestedNameSpecifierLoc(QualifierLoc))
759 return true;
760
761 return false;
762}
763
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000764/// \brief Compare two base or member initializers based on their source order.
765static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
766 CXXCtorInitializer *const *Y) {
767 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
768}
769
Guy Benyei11169dd2012-12-18 14:30:41 +0000770bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000771 unsigned NumParamList = ND->getNumTemplateParameterLists();
772 for (unsigned i = 0; i < NumParamList; i++) {
773 TemplateParameterList* Params = ND->getTemplateParameterList(i);
774 if (VisitTemplateParameters(Params))
775 return true;
776 }
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
779 // Visit the function declaration's syntactic components in the order
780 // written. This requires a bit of work.
781 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000782 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000783
784 // If we have a function declared directly (without the use of a typedef),
785 // visit just the return type. Otherwise, just visit the function's type
786 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000787 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 (!FTL && Visit(TL)))
789 return true;
790
791 // Visit the nested-name-specifier, if present.
792 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
793 if (VisitNestedNameSpecifierLoc(QualifierLoc))
794 return true;
795
796 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000797 if (!isa<CXXDestructorDecl>(ND))
798 if (VisitDeclarationNameInfo(ND->getNameInfo()))
799 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000800
801 // FIXME: Visit explicitly-specified template arguments!
802
803 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000804 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000805 return true;
806
Bill Wendling44426052012-12-20 19:22:21 +0000807 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000808 }
809
810 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
811 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
812 // Find the initializers that were written in the source.
813 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000814 for (auto *I : Constructor->inits()) {
815 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 continue;
817
Aaron Ballman0ad78302014-03-13 17:34:31 +0000818 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000819 }
820
821 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000822 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
823 &CompareCXXCtorInitializers);
824
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 // Visit the initializers in source order
826 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
827 CXXCtorInitializer *Init = WrittenInits[I];
828 if (Init->isAnyMemberInitializer()) {
829 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
830 Init->getMemberLocation(), TU)))
831 return true;
832 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
833 if (Visit(TInfo->getTypeLoc()))
834 return true;
835 }
836
837 // Visit the initializer value.
838 if (Expr *Initializer = Init->getInit())
839 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
840 return true;
841 }
842 }
843
844 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
845 return true;
846 }
847
848 return false;
849}
850
851bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
852 if (VisitDeclaratorDecl(D))
853 return true;
854
855 if (Expr *BitWidth = D->getBitWidth())
856 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
857
858 return false;
859}
860
861bool CursorVisitor::VisitVarDecl(VarDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *Init = D->getInit())
866 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
876 if (Expr *DefArg = D->getDefaultArgument())
877 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
878
879 return false;
880}
881
882bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
883 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
884 // before visiting these template parameters.
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 return VisitFunctionDecl(D->getTemplatedDecl());
889}
890
891bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the TagDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitCXXRecordDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
905 VisitTemplateArgumentLoc(D->getDefaultArgument()))
906 return true;
907
908 return false;
909}
910
911bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000912 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000913 if (Visit(TSInfo->getTypeLoc()))
914 return true;
915
Aaron Ballman43b68be2014-03-07 17:50:17 +0000916 for (const auto *P : ND->params()) {
917 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 return true;
919 }
920
921 if (ND->isThisDeclarationADefinition() &&
922 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
923 return true;
924
925 return false;
926}
927
928template <typename DeclIt>
929static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
930 SourceManager &SM, SourceLocation EndLoc,
931 SmallVectorImpl<Decl *> &Decls) {
932 DeclIt next = *DI_current;
933 while (++next != DE_current) {
934 Decl *D_next = *next;
935 if (!D_next)
936 break;
937 SourceLocation L = D_next->getLocStart();
938 if (!L.isValid())
939 break;
940 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
941 *DI_current = next;
942 Decls.push_back(D_next);
943 continue;
944 }
945 break;
946 }
947}
948
Guy Benyei11169dd2012-12-18 14:30:41 +0000949bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
950 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
951 // an @implementation can lexically contain Decls that are not properly
952 // nested in the AST. When we identify such cases, we need to retrofit
953 // this nesting here.
954 if (!DI_current && !FileDI_current)
955 return VisitDeclContext(D);
956
957 // Scan the Decls that immediately come after the container
958 // in the current DeclContext. If any fall within the
959 // container's lexical region, stash them into a vector
960 // for later processing.
961 SmallVector<Decl *, 24> DeclsInContainer;
962 SourceLocation EndLoc = D->getSourceRange().getEnd();
963 SourceManager &SM = AU->getSourceManager();
964 if (EndLoc.isValid()) {
965 if (DI_current) {
966 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
967 DeclsInContainer);
968 } else {
969 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
970 DeclsInContainer);
971 }
972 }
973
974 // The common case.
975 if (DeclsInContainer.empty())
976 return VisitDeclContext(D);
977
978 // Get all the Decls in the DeclContext, and sort them with the
979 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000980 for (auto *SubDecl : D->decls()) {
981 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
982 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000984 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000985 }
986
987 // Now sort the Decls so that they appear in lexical order.
988 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000989 [&SM](Decl *A, Decl *B) {
990 SourceLocation L_A = A->getLocStart();
991 SourceLocation L_B = B->getLocStart();
992 assert(L_A.isValid() && L_B.isValid());
993 return SM.isBeforeInTranslationUnit(L_A, L_B);
994 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000995
996 // Now visit the decls.
997 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
998 E = DeclsInContainer.end(); I != E; ++I) {
999 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001000 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!V.hasValue())
1002 continue;
1003 if (!V.getValue())
1004 return false;
1005 if (Visit(Cursor, true))
1006 return true;
1007 }
1008 return false;
1009}
1010
1011bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1012 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1013 TU)))
1014 return true;
1015
1016 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1017 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1018 E = ND->protocol_end(); I != E; ++I, ++PL)
1019 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1020 return true;
1021
1022 return VisitObjCContainerDecl(ND);
1023}
1024
1025bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1026 if (!PID->isThisDeclarationADefinition())
1027 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1028
1029 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1030 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1031 E = PID->protocol_end(); I != E; ++I, ++PL)
1032 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1033 return true;
1034
1035 return VisitObjCContainerDecl(PID);
1036}
1037
1038bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1039 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1040 return true;
1041
1042 // FIXME: This implements a workaround with @property declarations also being
1043 // installed in the DeclContext for the @interface. Eventually this code
1044 // should be removed.
1045 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1046 if (!CDecl || !CDecl->IsClassExtension())
1047 return false;
1048
1049 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1050 if (!ID)
1051 return false;
1052
1053 IdentifierInfo *PropertyId = PD->getIdentifier();
1054 ObjCPropertyDecl *prevDecl =
1055 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1056
1057 if (!prevDecl)
1058 return false;
1059
1060 // Visit synthesized methods since they will be skipped when visiting
1061 // the @interface.
1062 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1063 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1064 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1065 return true;
1066
1067 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1076 if (!D->isThisDeclarationADefinition()) {
1077 // Forward declaration is treated like a reference.
1078 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1079 }
1080
1081 // Issue callbacks for super class.
1082 if (D->getSuperClass() &&
1083 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1084 D->getSuperClassLoc(),
1085 TU)))
1086 return true;
1087
1088 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1089 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1090 E = D->protocol_end(); I != E; ++I, ++PL)
1091 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1092 return true;
1093
1094 return VisitObjCContainerDecl(D);
1095}
1096
1097bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1098 return VisitObjCContainerDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1102 // 'ID' could be null when dealing with invalid code.
1103 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1104 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1105 return true;
1106
1107 return VisitObjCImplDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1111#if 0
1112 // Issue callbacks for super class.
1113 // FIXME: No source location information!
1114 if (D->getSuperClass() &&
1115 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1116 D->getSuperClassLoc(),
1117 TU)))
1118 return true;
1119#endif
1120
1121 return VisitObjCImplDecl(D);
1122}
1123
1124bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1125 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1126 if (PD->isIvarNameSpecified())
1127 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1128
1129 return false;
1130}
1131
1132bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1133 return VisitDeclContext(D);
1134}
1135
1136bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1137 // Visit nested-name-specifier.
1138 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1139 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1140 return true;
1141
1142 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1143 D->getTargetNameLoc(), TU));
1144}
1145
1146bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1147 // Visit nested-name-specifier.
1148 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1149 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1150 return true;
1151 }
1152
1153 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1154 return true;
1155
1156 return VisitDeclarationNameInfo(D->getNameInfo());
1157}
1158
1159bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1160 // Visit nested-name-specifier.
1161 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1162 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1163 return true;
1164
1165 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1166 D->getIdentLocation(), TU));
1167}
1168
1169bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174 }
1175
1176 return VisitDeclarationNameInfo(D->getNameInfo());
1177}
1178
1179bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1180 UnresolvedUsingTypenameDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return false;
1187}
1188
1189bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1190 switch (Name.getName().getNameKind()) {
1191 case clang::DeclarationName::Identifier:
1192 case clang::DeclarationName::CXXLiteralOperatorName:
1193 case clang::DeclarationName::CXXOperatorName:
1194 case clang::DeclarationName::CXXUsingDirective:
1195 return false;
1196
1197 case clang::DeclarationName::CXXConstructorName:
1198 case clang::DeclarationName::CXXDestructorName:
1199 case clang::DeclarationName::CXXConversionFunctionName:
1200 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1201 return Visit(TSInfo->getTypeLoc());
1202 return false;
1203
1204 case clang::DeclarationName::ObjCZeroArgSelector:
1205 case clang::DeclarationName::ObjCOneArgSelector:
1206 case clang::DeclarationName::ObjCMultiArgSelector:
1207 // FIXME: Per-identifier location info?
1208 return false;
1209 }
1210
1211 llvm_unreachable("Invalid DeclarationName::Kind!");
1212}
1213
1214bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1215 SourceRange Range) {
1216 // FIXME: This whole routine is a hack to work around the lack of proper
1217 // source information in nested-name-specifiers (PR5791). Since we do have
1218 // a beginning source location, we can visit the first component of the
1219 // nested-name-specifier, if it's a single-token component.
1220 if (!NNS)
1221 return false;
1222
1223 // Get the first component in the nested-name-specifier.
1224 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1225 NNS = Prefix;
1226
1227 switch (NNS->getKind()) {
1228 case NestedNameSpecifier::Namespace:
1229 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1230 TU));
1231
1232 case NestedNameSpecifier::NamespaceAlias:
1233 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1234 Range.getBegin(), TU));
1235
1236 case NestedNameSpecifier::TypeSpec: {
1237 // If the type has a form where we know that the beginning of the source
1238 // range matches up with a reference cursor. Visit the appropriate reference
1239 // cursor.
1240 const Type *T = NNS->getAsType();
1241 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1242 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1243 if (const TagType *Tag = dyn_cast<TagType>(T))
1244 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1245 if (const TemplateSpecializationType *TST
1246 = dyn_cast<TemplateSpecializationType>(T))
1247 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1248 break;
1249 }
1250
1251 case NestedNameSpecifier::TypeSpecWithTemplate:
1252 case NestedNameSpecifier::Global:
1253 case NestedNameSpecifier::Identifier:
1254 break;
1255 }
1256
1257 return false;
1258}
1259
1260bool
1261CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1262 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1263 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1264 Qualifiers.push_back(Qualifier);
1265
1266 while (!Qualifiers.empty()) {
1267 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1268 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1269 switch (NNS->getKind()) {
1270 case NestedNameSpecifier::Namespace:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1272 Q.getLocalBeginLoc(),
1273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::TypeSpec:
1287 case NestedNameSpecifier::TypeSpecWithTemplate:
1288 if (Visit(Q.getTypeLoc()))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::Global:
1294 case NestedNameSpecifier::Identifier:
1295 break;
1296 }
1297 }
1298
1299 return false;
1300}
1301
1302bool CursorVisitor::VisitTemplateParameters(
1303 const TemplateParameterList *Params) {
1304 if (!Params)
1305 return false;
1306
1307 for (TemplateParameterList::const_iterator P = Params->begin(),
1308 PEnd = Params->end();
1309 P != PEnd; ++P) {
1310 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1318 switch (Name.getKind()) {
1319 case TemplateName::Template:
1320 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1321
1322 case TemplateName::OverloadedTemplate:
1323 // Visit the overloaded template set.
1324 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1325 return true;
1326
1327 return false;
1328
1329 case TemplateName::DependentTemplate:
1330 // FIXME: Visit nested-name-specifier.
1331 return false;
1332
1333 case TemplateName::QualifiedTemplate:
1334 // FIXME: Visit nested-name-specifier.
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsQualifiedTemplateName()->getDecl(),
1337 Loc, TU));
1338
1339 case TemplateName::SubstTemplateTemplateParm:
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParmPack:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1347 Loc, TU));
1348 }
1349
1350 llvm_unreachable("Invalid TemplateName::Kind!");
1351}
1352
1353bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1354 switch (TAL.getArgument().getKind()) {
1355 case TemplateArgument::Null:
1356 case TemplateArgument::Integral:
1357 case TemplateArgument::Pack:
1358 return false;
1359
1360 case TemplateArgument::Type:
1361 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1362 return Visit(TSInfo->getTypeLoc());
1363 return false;
1364
1365 case TemplateArgument::Declaration:
1366 if (Expr *E = TAL.getSourceDeclExpression())
1367 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1368 return false;
1369
1370 case TemplateArgument::NullPtr:
1371 if (Expr *E = TAL.getSourceNullPtrExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::Expression:
1376 if (Expr *E = TAL.getSourceExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Template:
1381 case TemplateArgument::TemplateExpansion:
1382 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1383 return true;
1384
1385 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1386 TAL.getTemplateNameLoc());
1387 }
1388
1389 llvm_unreachable("Invalid TemplateArgument::Kind!");
1390}
1391
1392bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1393 return VisitDeclContext(D);
1394}
1395
1396bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1397 return Visit(TL.getUnqualifiedLoc());
1398}
1399
1400bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1401 ASTContext &Context = AU->getASTContext();
1402
1403 // Some builtin types (such as Objective-C's "id", "sel", and
1404 // "Class") have associated declarations. Create cursors for those.
1405 QualType VisitType;
1406 switch (TL.getTypePtr()->getKind()) {
1407
1408 case BuiltinType::Void:
1409 case BuiltinType::NullPtr:
1410 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001411 case BuiltinType::OCLImage1d:
1412 case BuiltinType::OCLImage1dArray:
1413 case BuiltinType::OCLImage1dBuffer:
1414 case BuiltinType::OCLImage2d:
1415 case BuiltinType::OCLImage2dArray:
1416 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001417 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001418 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001419#define BUILTIN_TYPE(Id, SingletonId)
1420#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#include "clang/AST/BuiltinTypes.def"
1425 break;
1426
1427 case BuiltinType::ObjCId:
1428 VisitType = Context.getObjCIdType();
1429 break;
1430
1431 case BuiltinType::ObjCClass:
1432 VisitType = Context.getObjCClassType();
1433 break;
1434
1435 case BuiltinType::ObjCSel:
1436 VisitType = Context.getObjCSelType();
1437 break;
1438 }
1439
1440 if (!VisitType.isNull()) {
1441 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1442 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1443 TU));
1444 }
1445
1446 return false;
1447}
1448
1449bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1458 if (TL.isDefinition())
1459 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1460
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1469 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1470 return true;
1471
1472 return false;
1473}
1474
1475bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1476 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1477 return true;
1478
1479 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1480 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1481 TU)))
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1493 return Visit(TL.getInnerLoc());
1494}
1495
1496bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1501 return Visit(TL.getPointeeLoc());
1502}
1503
1504bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1517 return Visit(TL.getModifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1521 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001522 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001523 return true;
1524
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001525 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1526 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001527 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1528 return true;
1529
1530 return false;
1531}
1532
1533bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1534 if (Visit(TL.getElementLoc()))
1535 return true;
1536
1537 if (Expr *Size = TL.getSizeExpr())
1538 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1539
1540 return false;
1541}
1542
Reid Kleckner8a365022013-06-24 17:51:48 +00001543bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1544 return Visit(TL.getOriginalLoc());
1545}
1546
Reid Kleckner0503a872013-12-05 01:23:43 +00001547bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1548 return Visit(TL.getOriginalLoc());
1549}
1550
Guy Benyei11169dd2012-12-18 14:30:41 +00001551bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1552 TemplateSpecializationTypeLoc TL) {
1553 // Visit the template name.
1554 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1555 TL.getTemplateNameLoc()))
1556 return true;
1557
1558 // Visit the template arguments.
1559 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1560 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1561 return true;
1562
1563 return false;
1564}
1565
1566bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1567 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1568}
1569
1570bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1571 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1572 return Visit(TSInfo->getTypeLoc());
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1585 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1592 DependentTemplateSpecializationTypeLoc TL) {
1593 // Visit the nested-name-specifier, if there is one.
1594 if (TL.getQualifierLoc() &&
1595 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 // Visit the template arguments.
1599 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1600 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1607 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1608 return true;
1609
1610 return Visit(TL.getNamedTypeLoc());
1611}
1612
1613bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1614 return Visit(TL.getPatternLoc());
1615}
1616
1617bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1618 if (Expr *E = TL.getUnderlyingExpr())
1619 return Visit(MakeCXCursor(E, StmtParent, TU));
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1625 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1626}
1627
1628bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1629 return Visit(TL.getValueLoc());
1630}
1631
1632#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1633bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1634 return Visit##PARENT##Loc(TL); \
1635}
1636
1637DEFAULT_TYPELOC_IMPL(Complex, Type)
1638DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1643DEFAULT_TYPELOC_IMPL(Vector, Type)
1644DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1645DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1646DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(Record, TagType)
1648DEFAULT_TYPELOC_IMPL(Enum, TagType)
1649DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1651DEFAULT_TYPELOC_IMPL(Auto, Type)
1652
1653bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1654 // Visit the nested-name-specifier, if present.
1655 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1656 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1657 return true;
1658
1659 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001660 for (const auto &I : D->bases()) {
1661 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001662 return true;
1663 }
1664 }
1665
1666 return VisitTagDecl(D);
1667}
1668
1669bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001670 for (const auto *I : D->attrs())
1671 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001706 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001853 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001854 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001855 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001856 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001857 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858
Guy Benyei11169dd2012-12-18 14:30:41 +00001859private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1862 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1864 void AddStmt(const Stmt *S);
1865 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869};
1870} // end anonyous namespace
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 // 'S' should always be non-null, since it comes from the
1874 // statement we are visiting.
1875 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1876}
1877
1878void
1879EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1880 if (Qualifier)
1881 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1882}
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (S)
1886 WL.push_back(StmtVisit(S, Parent));
1887}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 if (D)
1890 WL.push_back(DeclVisit(D, Parent, isFirst));
1891}
1892void EnqueueVisitor::
1893 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1894 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001896}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (D)
1899 WL.push_back(MemberRefVisit(D, L, Parent));
1900}
1901void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1902 if (TI)
1903 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1904 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 AddStmt(*Child);
1909 }
1910 if (size == WL.size())
1911 return;
1912 // Now reverse the entries we just added. This will match the DFS
1913 // ordering performed by the worklist.
1914 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1915 std::reverse(I, E);
1916}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917namespace {
1918class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1919 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001920 /// \brief Process clauses with list of variables.
1921 template <typename T>
1922 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923public:
1924 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1925#define OPENMP_CLAUSE(Name, Class) \
1926 void Visit##Class(const Class *C);
1927#include "clang/Basic/OpenMPKinds.def"
1928};
1929
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001930void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1931 Visitor->AddStmt(C->getCondition());
1932}
1933
Alexey Bataev568a8332014-03-06 06:15:19 +00001934void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1935 Visitor->AddStmt(C->getNumThreads());
1936}
1937
Alexey Bataev62c87d22014-03-21 04:51:18 +00001938void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1939 Visitor->AddStmt(C->getSafelen());
1940}
1941
Alexander Musman8bd31e62014-05-27 15:12:19 +00001942void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1943 Visitor->AddStmt(C->getNumForLoops());
1944}
1945
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001947
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001948void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1949
Alexey Bataev56dafe82014-06-20 07:16:17 +00001950void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1951 Visitor->AddStmt(C->getChunkSize());
1952}
1953
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001954void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1955
Alexey Bataev236070f2014-06-20 11:19:47 +00001956void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1957
Alexey Bataev756c1962013-09-24 03:17:45 +00001958template<typename T>
1959void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001960 for (const auto *I : Node->varlists())
1961 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001962}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963
1964void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001965 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001967void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1968 const OMPFirstprivateClause *C) {
1969 VisitOMPClauseList(C);
1970}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001971void OMPClauseEnqueue::VisitOMPLastprivateClause(
1972 const OMPLastprivateClause *C) {
1973 VisitOMPClauseList(C);
1974}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001975void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001976 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001977}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001978void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1979 VisitOMPClauseList(C);
1980}
Alexander Musman8dba6642014-04-22 13:09:42 +00001981void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1982 VisitOMPClauseList(C);
1983 Visitor->AddStmt(C->getStep());
1984}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001985void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1986 VisitOMPClauseList(C);
1987 Visitor->AddStmt(C->getAlignment());
1988}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001989void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1990 VisitOMPClauseList(C);
1991}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001992void
1993OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
1994 VisitOMPClauseList(C);
1995}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001996}
Alexey Bataev756c1962013-09-24 03:17:45 +00001997
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001998void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1999 unsigned size = WL.size();
2000 OMPClauseEnqueue Visitor(this);
2001 Visitor.Visit(S);
2002 if (size == WL.size())
2003 return;
2004 // Now reverse the entries we just added. This will match the DFS
2005 // ordering performed by the worklist.
2006 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2007 std::reverse(I, E);
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2011}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002012void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002013 AddDecl(B->getBlockDecl());
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 EnqueueChildren(E);
2017 AddTypeLoc(E->getTypeSourceInfo());
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2020 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 E = S->body_rend(); I != E; ++I) {
2022 AddStmt(*I);
2023 }
2024}
2025void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 AddStmt(S->getSubStmt());
2028 AddDeclarationNameInfo(S);
2029 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2030 AddNestedNameSpecifierLoc(QualifierLoc);
2031}
2032
2033void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2036 AddDeclarationNameInfo(E);
2037 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2038 AddNestedNameSpecifierLoc(QualifierLoc);
2039 if (!E->isImplicitAccess())
2040 AddStmt(E->getBase());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 // Enqueue the initializer , if any.
2044 AddStmt(E->getInitializer());
2045 // Enqueue the array size, if any.
2046 AddStmt(E->getArraySize());
2047 // Enqueue the allocated type.
2048 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2049 // Enqueue the placement arguments.
2050 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2051 AddStmt(E->getPlacementArg(I-1));
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2055 AddStmt(CE->getArg(I-1));
2056 AddStmt(CE->getCallee());
2057 AddStmt(CE->getArg(0));
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2060 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 // Visit the name of the type being destroyed.
2062 AddTypeLoc(E->getDestroyedTypeInfo());
2063 // Visit the scope type that looks disturbingly like the nested-name-specifier
2064 // but isn't.
2065 AddTypeLoc(E->getScopeTypeInfo());
2066 // Visit the nested-name-specifier.
2067 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2068 AddNestedNameSpecifierLoc(QualifierLoc);
2069 // Visit base expression.
2070 AddStmt(E->getBase());
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2073 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddTypeLoc(E->getTypeSourceInfo());
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2077 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 EnqueueChildren(E);
2079 AddTypeLoc(E->getTypeSourceInfo());
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 EnqueueChildren(E);
2083 if (E->isTypeOperand())
2084 AddTypeLoc(E->getTypeOperandSourceInfo());
2085}
2086
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2088 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 EnqueueChildren(E);
2090 AddTypeLoc(E->getTypeSourceInfo());
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 EnqueueChildren(E);
2094 if (E->isTypeOperand())
2095 AddTypeLoc(E->getTypeOperandSourceInfo());
2096}
2097
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(S);
2100 AddDecl(S->getExceptionDecl());
2101}
2102
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 if (DR->hasExplicitTemplateArgs()) {
2105 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2106 }
2107 WL.push_back(DeclRefExprParts(DR, Parent));
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2110 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2112 AddDeclarationNameInfo(E);
2113 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 unsigned size = WL.size();
2117 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002118 for (const auto *D : S->decls()) {
2119 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 isFirst = false;
2121 }
2122 if (size == WL.size())
2123 return;
2124 // Now reverse the entries we just added. This will match the DFS
2125 // ordering performed by the worklist.
2126 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2127 std::reverse(I, E);
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 D = E->designators_rbegin(), DEnd = E->designators_rend();
2133 D != DEnd; ++D) {
2134 if (D->isFieldDesignator()) {
2135 if (FieldDecl *Field = D->getField())
2136 AddMemberRef(Field, D->getFieldLoc());
2137 continue;
2138 }
2139 if (D->isArrayDesignator()) {
2140 AddStmt(E->getArrayIndex(*D));
2141 continue;
2142 }
2143 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2144 AddStmt(E->getArrayRangeEnd(*D));
2145 AddStmt(E->getArrayRangeStart(*D));
2146 }
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 EnqueueChildren(E);
2150 AddTypeLoc(E->getTypeInfoAsWritten());
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 AddStmt(FS->getBody());
2154 AddStmt(FS->getInc());
2155 AddStmt(FS->getCond());
2156 AddDecl(FS->getConditionVariable());
2157 AddStmt(FS->getInit());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 AddStmt(If->getElse());
2164 AddStmt(If->getThen());
2165 AddStmt(If->getCond());
2166 AddDecl(If->getConditionVariable());
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 // We care about the syntactic form of the initializer list, only.
2170 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2171 IE = Syntactic;
2172 EnqueueChildren(IE);
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 WL.push_back(MemberExprParts(M, Parent));
2176
2177 // If the base of the member access expression is an implicit 'this', don't
2178 // visit it.
2179 // FIXME: If we ever want to show these implicit accesses, this will be
2180 // unfortunate. However, clang_getCursor() relies on this behavior.
2181 if (!M->isImplicitAccess())
2182 AddStmt(M->getBase());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getEncodedTypeSourceInfo());
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 EnqueueChildren(M);
2189 AddTypeLoc(M->getClassReceiverTypeInfo());
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 // Visit the components of the offsetof expression.
2193 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2194 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2195 const OffsetOfNode &Node = E->getComponent(I-1);
2196 switch (Node.getKind()) {
2197 case OffsetOfNode::Array:
2198 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2199 break;
2200 case OffsetOfNode::Field:
2201 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2202 break;
2203 case OffsetOfNode::Identifier:
2204 case OffsetOfNode::Base:
2205 continue;
2206 }
2207 }
2208 // Visit the type into which we're computing the offset.
2209 AddTypeLoc(E->getTypeSourceInfo());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2213 WL.push_back(OverloadExprParts(E, Parent));
2214}
2215void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 EnqueueChildren(E);
2218 if (E->isArgumentType())
2219 AddTypeLoc(E->getArgumentTypeInfo());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 EnqueueChildren(S);
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(S->getBody());
2226 AddStmt(S->getCond());
2227 AddDecl(S->getConditionVariable());
2228}
2229
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddStmt(W->getBody());
2232 AddStmt(W->getCond());
2233 AddDecl(W->getConditionVariable());
2234}
2235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 for (unsigned I = E->getNumArgs(); I > 0; --I)
2238 AddTypeLoc(E->getArg(I-1));
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 AddTypeLoc(E->getQueriedTypeSourceInfo());
2243}
2244
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 EnqueueChildren(E);
2247}
2248
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 VisitOverloadExpr(U);
2251 if (!U->isImplicitAccess())
2252 AddStmt(U->getBase());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 AddStmt(E->getSubExpr());
2256 AddTypeLoc(E->getWrittenTypeInfo());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 WL.push_back(SizeOfPackExprParts(E, Parent));
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 // If the opaque value has a source expression, just transparently
2263 // visit that. This is useful for (e.g.) pseudo-object expressions.
2264 if (Expr *SourceExpr = E->getSourceExpr())
2265 return Visit(SourceExpr);
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddStmt(E->getBody());
2269 WL.push_back(LambdaExprParts(E, Parent));
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 // Treat the expression like its syntactic form.
2273 Visit(E->getSyntacticForm());
2274}
2275
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002276void EnqueueVisitor::VisitOMPExecutableDirective(
2277 const OMPExecutableDirective *D) {
2278 EnqueueChildren(D);
2279 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2280 E = D->clauses().end();
2281 I != E; ++I)
2282 EnqueueChildren(*I);
2283}
2284
2285void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2286 VisitOMPExecutableDirective(D);
2287}
2288
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002289void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2290 VisitOMPExecutableDirective(D);
2291}
2292
Alexey Bataevf29276e2014-06-18 04:14:57 +00002293void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2294 VisitOMPExecutableDirective(D);
2295}
2296
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002297void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2298 VisitOMPExecutableDirective(D);
2299}
2300
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002301void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2302 VisitOMPExecutableDirective(D);
2303}
2304
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002305void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2306 VisitOMPExecutableDirective(D);
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2311}
2312
2313bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2314 if (RegionOfInterest.isValid()) {
2315 SourceRange Range = getRawCursorExtent(C);
2316 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2317 return false;
2318 }
2319 return true;
2320}
2321
2322bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2323 while (!WL.empty()) {
2324 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002325 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002326
2327 // Set the Parent field, then back to its old value once we're done.
2328 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2329
2330 switch (LI.getKind()) {
2331 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 if (!D)
2334 continue;
2335
2336 // For now, perform default visitation for Decls.
2337 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2338 cast<DeclVisit>(&LI)->isFirst())))
2339 return true;
2340
2341 continue;
2342 }
2343 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2344 const ASTTemplateArgumentListInfo *ArgList =
2345 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2346 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2347 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2348 Arg != ArgEnd; ++Arg) {
2349 if (VisitTemplateArgumentLoc(*Arg))
2350 return true;
2351 }
2352 continue;
2353 }
2354 case VisitorJob::TypeLocVisitKind: {
2355 // Perform default visitation for TypeLocs.
2356 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2357 return true;
2358 continue;
2359 }
2360 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002361 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002362 if (LabelStmt *stmt = LS->getStmt()) {
2363 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2364 TU))) {
2365 return true;
2366 }
2367 }
2368 continue;
2369 }
2370
2371 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2372 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2373 if (VisitNestedNameSpecifierLoc(V->get()))
2374 return true;
2375 continue;
2376 }
2377
2378 case VisitorJob::DeclarationNameInfoVisitKind: {
2379 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2380 ->get()))
2381 return true;
2382 continue;
2383 }
2384 case VisitorJob::MemberRefVisitKind: {
2385 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2386 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2387 return true;
2388 continue;
2389 }
2390 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 if (!S)
2393 continue;
2394
2395 // Update the current cursor.
2396 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2397 if (!IsInRegionOfInterest(Cursor))
2398 continue;
2399 switch (Visitor(Cursor, Parent, ClientData)) {
2400 case CXChildVisit_Break: return true;
2401 case CXChildVisit_Continue: break;
2402 case CXChildVisit_Recurse:
2403 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002404 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002405 EnqueueWorkList(WL, S);
2406 break;
2407 }
2408 continue;
2409 }
2410 case VisitorJob::MemberExprPartsKind: {
2411 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002413
2414 // Visit the nested-name-specifier
2415 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2416 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2417 return true;
2418
2419 // Visit the declaration name.
2420 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2421 return true;
2422
2423 // Visit the explicitly-specified template arguments, if any.
2424 if (M->hasExplicitTemplateArgs()) {
2425 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2426 *ArgEnd = Arg + M->getNumTemplateArgs();
2427 Arg != ArgEnd; ++Arg) {
2428 if (VisitTemplateArgumentLoc(*Arg))
2429 return true;
2430 }
2431 }
2432 continue;
2433 }
2434 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 // Visit nested-name-specifier, if present.
2437 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2438 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2439 return true;
2440 // Visit declaration name.
2441 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2442 return true;
2443 continue;
2444 }
2445 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 // Visit the nested-name-specifier.
2448 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2449 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2450 return true;
2451 // Visit the declaration name.
2452 if (VisitDeclarationNameInfo(O->getNameInfo()))
2453 return true;
2454 // Visit the overloaded declaration reference.
2455 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2456 return true;
2457 continue;
2458 }
2459 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002460 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002461 NamedDecl *Pack = E->getPack();
2462 if (isa<TemplateTypeParmDecl>(Pack)) {
2463 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2464 E->getPackLoc(), TU)))
2465 return true;
2466
2467 continue;
2468 }
2469
2470 if (isa<TemplateTemplateParmDecl>(Pack)) {
2471 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2472 E->getPackLoc(), TU)))
2473 return true;
2474
2475 continue;
2476 }
2477
2478 // Non-type template parameter packs and function parameter packs are
2479 // treated like DeclRefExpr cursors.
2480 continue;
2481 }
2482
2483 case VisitorJob::LambdaExprPartsKind: {
2484 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002485 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002486 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2487 CEnd = E->explicit_capture_end();
2488 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002489 // FIXME: Lambda init-captures.
2490 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002492
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2494 C->getLocation(),
2495 TU)))
2496 return true;
2497 }
2498
2499 // Visit parameters and return type, if present.
2500 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2501 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2502 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2503 // Visit the whole type.
2504 if (Visit(TL))
2505 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002506 } else if (FunctionProtoTypeLoc Proto =
2507 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 if (E->hasExplicitParameters()) {
2509 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002510 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2511 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 return true;
2513 } else {
2514 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002515 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 return true;
2517 }
2518 }
2519 }
2520 break;
2521 }
2522
2523 case VisitorJob::PostChildrenVisitKind:
2524 if (PostChildrenVisitor(Parent, ClientData))
2525 return true;
2526 break;
2527 }
2528 }
2529 return false;
2530}
2531
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002533 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 if (!WorkListFreeList.empty()) {
2535 WL = WorkListFreeList.back();
2536 WL->clear();
2537 WorkListFreeList.pop_back();
2538 }
2539 else {
2540 WL = new VisitorWorkList();
2541 WorkListCache.push_back(WL);
2542 }
2543 EnqueueWorkList(*WL, S);
2544 bool result = RunVisitorWorkList(*WL);
2545 WorkListFreeList.push_back(WL);
2546 return result;
2547}
2548
2549namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002550typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002551RefNamePieces
2552buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2553 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2554 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2556 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2557 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2558
2559 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2560
2561 RefNamePieces Pieces;
2562
2563 if (WantQualifier && QLoc.isValid())
2564 Pieces.push_back(QLoc);
2565
2566 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2567 Pieces.push_back(NI.getLoc());
2568
2569 if (WantTemplateArgs && TemplateArgs)
2570 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2571 TemplateArgs->RAngleLoc));
2572
2573 if (Kind == DeclarationName::CXXOperatorName) {
2574 Pieces.push_back(SourceLocation::getFromRawEncoding(
2575 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2576 Pieces.push_back(SourceLocation::getFromRawEncoding(
2577 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2578 }
2579
2580 if (WantSinglePiece) {
2581 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2582 Pieces.clear();
2583 Pieces.push_back(R);
2584 }
2585
2586 return Pieces;
2587}
2588}
2589
2590//===----------------------------------------------------------------------===//
2591// Misc. API hooks.
2592//===----------------------------------------------------------------------===//
2593
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002594static llvm::sys::Mutex EnableMultithreadingMutex;
2595static bool EnabledMultithreading;
Guy Benyei11169dd2012-12-18 14:30:41 +00002596
Chad Rosier05c71aa2013-03-27 18:28:23 +00002597static void fatal_error_handler(void *user_data, const std::string& reason,
2598 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 // Write the result out to stderr avoiding errs() because raw_ostreams can
2600 // call report_fatal_error.
2601 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2602 ::abort();
2603}
2604
2605extern "C" {
2606CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2607 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002608 // We use crash recovery to make some of our APIs more reliable, implicitly
2609 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002610 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2611 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002612
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002613 // Enable support for multithreading in LLVM.
2614 {
2615 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2616 if (!EnabledMultithreading) {
2617 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2618 llvm::llvm_start_multithreaded();
2619 EnabledMultithreading = true;
2620 }
2621 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002622
2623 CIndexer *CIdxr = new CIndexer();
2624 if (excludeDeclarationsFromPCH)
2625 CIdxr->setOnlyLocalDecls();
2626 if (displayDiagnostics)
2627 CIdxr->setDisplayDiagnostics();
2628
2629 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2630 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2631 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2632 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2633 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2634 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2635
2636 return CIdxr;
2637}
2638
2639void clang_disposeIndex(CXIndex CIdx) {
2640 if (CIdx)
2641 delete static_cast<CIndexer *>(CIdx);
2642}
2643
2644void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2645 if (CIdx)
2646 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2647}
2648
2649unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2650 if (CIdx)
2651 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2652 return 0;
2653}
2654
2655void clang_toggleCrashRecovery(unsigned isEnabled) {
2656 if (isEnabled)
2657 llvm::CrashRecoveryContext::Enable();
2658 else
2659 llvm::CrashRecoveryContext::Disable();
2660}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002661
Guy Benyei11169dd2012-12-18 14:30:41 +00002662CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2663 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002664 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002665 enum CXErrorCode Result =
2666 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002667 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668 assert((TU && Result == CXError_Success) ||
2669 (!TU && Result != CXError_Success));
2670 return TU;
2671}
2672
2673enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2674 const char *ast_filename,
2675 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002676 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002677 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002678
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002679 if (!CIdx || !ast_filename || !out_TU)
2680 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002681
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002682 LOG_FUNC_SECTION {
2683 *Log << ast_filename;
2684 }
2685
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2687 FileSystemOptions FileSystemOpts;
2688
2689 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002690 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002691 CXXIdx->getOnlyLocalDecls(), None,
2692 /*CaptureDiagnostics=*/true,
2693 /*AllowPCHWithCompilerErrors=*/true,
2694 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002695 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2696 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002697}
2698
2699unsigned clang_defaultEditingTranslationUnitOptions() {
2700 return CXTranslationUnit_PrecompiledPreamble |
2701 CXTranslationUnit_CacheCompletionResults;
2702}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703
Guy Benyei11169dd2012-12-18 14:30:41 +00002704CXTranslationUnit
2705clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2706 const char *source_filename,
2707 int num_command_line_args,
2708 const char * const *command_line_args,
2709 unsigned num_unsaved_files,
2710 struct CXUnsavedFile *unsaved_files) {
2711 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2712 return clang_parseTranslationUnit(CIdx, source_filename,
2713 command_line_args, num_command_line_args,
2714 unsaved_files, num_unsaved_files,
2715 Options);
2716}
2717
2718struct ParseTranslationUnitInfo {
2719 CXIndex CIdx;
2720 const char *source_filename;
2721 const char *const *command_line_args;
2722 int num_command_line_args;
2723 struct CXUnsavedFile *unsaved_files;
2724 unsigned num_unsaved_files;
2725 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002726 CXTranslationUnit *out_TU;
2727 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002728};
2729static void clang_parseTranslationUnit_Impl(void *UserData) {
2730 ParseTranslationUnitInfo *PTUI =
2731 static_cast<ParseTranslationUnitInfo*>(UserData);
2732 CXIndex CIdx = PTUI->CIdx;
2733 const char *source_filename = PTUI->source_filename;
2734 const char * const *command_line_args = PTUI->command_line_args;
2735 int num_command_line_args = PTUI->num_command_line_args;
2736 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2737 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2738 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002739 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002740
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002741 // Set up the initial return values.
2742 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002743 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002744 PTUI->result = CXError_Failure;
2745
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002746 // Check arguments.
2747 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002748 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002750 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002751 }
2752
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2754
2755 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2756 setThreadBackgroundPriority();
2757
2758 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2759 // FIXME: Add a flag for modules.
2760 TranslationUnitKind TUKind
2761 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002762 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002763 = options & CXTranslationUnit_CacheCompletionResults;
2764 bool IncludeBriefCommentsInCodeCompletion
2765 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2766 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2767 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2768
2769 // Configure the diagnostics.
2770 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002771 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002772
2773 // Recover resources if we crash before exiting this function.
2774 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2775 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2776 DiagCleanup(Diags.getPtr());
2777
Ahmed Charlesb8984322014-03-07 20:03:18 +00002778 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2779 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002780
2781 // Recover resources if we crash before exiting this function.
2782 llvm::CrashRecoveryContextCleanupRegistrar<
2783 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2784
2785 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2786 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2787 const llvm::MemoryBuffer *Buffer
2788 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2789 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2790 Buffer));
2791 }
2792
Ahmed Charlesb8984322014-03-07 20:03:18 +00002793 std::unique_ptr<std::vector<const char *>> Args(
2794 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002795
2796 // Recover resources if we crash before exiting this method.
2797 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2798 ArgsCleanup(Args.get());
2799
2800 // Since the Clang C library is primarily used by batch tools dealing with
2801 // (often very broken) source code, where spell-checking can have a
2802 // significant negative impact on performance (particularly when
2803 // precompiled headers are involved), we disable it by default.
2804 // Only do this if we haven't found a spell-checking-related argument.
2805 bool FoundSpellCheckingArgument = false;
2806 for (int I = 0; I != num_command_line_args; ++I) {
2807 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2808 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2809 FoundSpellCheckingArgument = true;
2810 break;
2811 }
2812 }
2813 if (!FoundSpellCheckingArgument)
2814 Args->push_back("-fno-spell-checking");
2815
2816 Args->insert(Args->end(), command_line_args,
2817 command_line_args + num_command_line_args);
2818
2819 // The 'source_filename' argument is optional. If the caller does not
2820 // specify it then it is assumed that the source file is specified
2821 // in the actual argument list.
2822 // Put the source file after command_line_args otherwise if '-x' flag is
2823 // present it will be unused.
2824 if (source_filename)
2825 Args->push_back(source_filename);
2826
2827 // Do we need the detailed preprocessing record?
2828 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2829 Args->push_back("-Xclang");
2830 Args->push_back("-detailed-preprocessing-record");
2831 }
2832
2833 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002834 std::unique_ptr<ASTUnit> ErrUnit;
2835 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002836 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002837 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2838 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2839 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2840 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2841 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2842 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002843
2844 if (NumErrors != Diags->getClient()->getNumErrors()) {
2845 // Make sure to check that 'Unit' is non-NULL.
2846 if (CXXIdx->getDisplayDiagnostics())
2847 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2848 }
2849
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002850 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2851 PTUI->result = CXError_ASTReadError;
2852 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002853 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2855 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002856}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857
2858CXTranslationUnit
2859clang_parseTranslationUnit(CXIndex CIdx,
2860 const char *source_filename,
2861 const char *const *command_line_args,
2862 int num_command_line_args,
2863 struct CXUnsavedFile *unsaved_files,
2864 unsigned num_unsaved_files,
2865 unsigned options) {
2866 CXTranslationUnit TU;
2867 enum CXErrorCode Result = clang_parseTranslationUnit2(
2868 CIdx, source_filename, command_line_args, num_command_line_args,
2869 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002870 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002871 assert((TU && Result == CXError_Success) ||
2872 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002873 return TU;
2874}
2875
2876enum CXErrorCode clang_parseTranslationUnit2(
2877 CXIndex CIdx,
2878 const char *source_filename,
2879 const char *const *command_line_args,
2880 int num_command_line_args,
2881 struct CXUnsavedFile *unsaved_files,
2882 unsigned num_unsaved_files,
2883 unsigned options,
2884 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002885 LOG_FUNC_SECTION {
2886 *Log << source_filename << ": ";
2887 for (int i = 0; i != num_command_line_args; ++i)
2888 *Log << command_line_args[i] << " ";
2889 }
2890
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2892 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002893 num_unsaved_files, options, out_TU,
2894 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 llvm::CrashRecoveryContext CRC;
2896
2897 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2898 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2899 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2900 fprintf(stderr, " 'command_line_args' : [");
2901 for (int i = 0; i != num_command_line_args; ++i) {
2902 if (i)
2903 fprintf(stderr, ", ");
2904 fprintf(stderr, "'%s'", command_line_args[i]);
2905 }
2906 fprintf(stderr, "],\n");
2907 fprintf(stderr, " 'unsaved_files' : [");
2908 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2909 if (i)
2910 fprintf(stderr, ", ");
2911 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2912 unsaved_files[i].Length);
2913 }
2914 fprintf(stderr, "],\n");
2915 fprintf(stderr, " 'options' : %d,\n", options);
2916 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002917
2918 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002920 if (CXTranslationUnit *TU = PTUI.out_TU)
2921 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002922 }
2923
2924 return PTUI.result;
2925}
2926
2927unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2928 return CXSaveTranslationUnit_None;
2929}
2930
2931namespace {
2932
2933struct SaveTranslationUnitInfo {
2934 CXTranslationUnit TU;
2935 const char *FileName;
2936 unsigned options;
2937 CXSaveError result;
2938};
2939
2940}
2941
2942static void clang_saveTranslationUnit_Impl(void *UserData) {
2943 SaveTranslationUnitInfo *STUI =
2944 static_cast<SaveTranslationUnitInfo*>(UserData);
2945
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002946 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2948 setThreadBackgroundPriority();
2949
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002950 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2952}
2953
2954int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2955 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002956 LOG_FUNC_SECTION {
2957 *Log << TU << ' ' << FileName;
2958 }
2959
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002960 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002961 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002963 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002964
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002965 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2967 if (!CXXUnit->hasSema())
2968 return CXSaveError_InvalidTU;
2969
2970 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2971
2972 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2973 getenv("LIBCLANG_NOTHREADS")) {
2974 clang_saveTranslationUnit_Impl(&STUI);
2975
2976 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2977 PrintLibclangResourceUsage(TU);
2978
2979 return STUI.result;
2980 }
2981
2982 // We have an AST that has invalid nodes due to compiler errors.
2983 // Use a crash recovery thread for protection.
2984
2985 llvm::CrashRecoveryContext CRC;
2986
2987 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2988 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2989 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2990 fprintf(stderr, " 'options' : %d,\n", options);
2991 fprintf(stderr, "}\n");
2992
2993 return CXSaveError_Unknown;
2994
2995 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2996 PrintLibclangResourceUsage(TU);
2997 }
2998
2999 return STUI.result;
3000}
3001
3002void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3003 if (CTUnit) {
3004 // If the translation unit has been marked as unsafe to free, just discard
3005 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3007 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 return;
3009
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003010 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003011 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3013 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003014 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 delete CTUnit;
3016 }
3017}
3018
3019unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3020 return CXReparse_None;
3021}
3022
3023struct ReparseTranslationUnitInfo {
3024 CXTranslationUnit TU;
3025 unsigned num_unsaved_files;
3026 struct CXUnsavedFile *unsaved_files;
3027 unsigned options;
3028 int result;
3029};
3030
3031static void clang_reparseTranslationUnit_Impl(void *UserData) {
3032 ReparseTranslationUnitInfo *RTUI =
3033 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003034 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003035
Guy Benyei11169dd2012-12-18 14:30:41 +00003036 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3038 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3039 unsigned options = RTUI->options;
3040 (void) options;
3041
3042 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003043 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003044 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 RTUI->result = CXError_InvalidArguments;
3046 return;
3047 }
Craig Topper69186e72014-06-08 08:38:04 +00003048 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003049 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003050 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003051 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003052
3053 // Reset the associated diagnostics.
3054 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003055 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003057 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3059 setThreadBackgroundPriority();
3060
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003061 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003062 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003063
3064 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3065 new std::vector<ASTUnit::RemappedFile>());
3066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 // Recover resources if we crash before exiting this function.
3068 llvm::CrashRecoveryContextCleanupRegistrar<
3069 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3070
3071 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3072 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3073 const llvm::MemoryBuffer *Buffer
3074 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3075 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3076 Buffer));
3077 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003078
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003079 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003080 RTUI->result = CXError_Success;
3081 else if (isASTReadError(CXXUnit))
3082 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003083}
3084
3085int clang_reparseTranslationUnit(CXTranslationUnit TU,
3086 unsigned num_unsaved_files,
3087 struct CXUnsavedFile *unsaved_files,
3088 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003089 LOG_FUNC_SECTION {
3090 *Log << TU;
3091 }
3092
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003094 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
3096 if (getenv("LIBCLANG_NOTHREADS")) {
3097 clang_reparseTranslationUnit_Impl(&RTUI);
3098 return RTUI.result;
3099 }
3100
3101 llvm::CrashRecoveryContext CRC;
3102
3103 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3104 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003105 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3108 PrintLibclangResourceUsage(TU);
3109
3110 return RTUI.result;
3111}
3112
3113
3114CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003115 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003116 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003117 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003121 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003122}
3123
3124CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003127 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3132}
3133
3134} // end: extern "C"
3135
3136//===----------------------------------------------------------------------===//
3137// CXFile Operations.
3138//===----------------------------------------------------------------------===//
3139
3140extern "C" {
3141CXString clang_getFileName(CXFile SFile) {
3142 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003143 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003144
3145 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003146 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003147}
3148
3149time_t clang_getFileTime(CXFile SFile) {
3150 if (!SFile)
3151 return 0;
3152
3153 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3154 return FEnt->getModificationTime();
3155}
3156
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003157CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003158 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003159 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003160 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003161 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003162
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003163 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003164
3165 FileManager &FMgr = CXXUnit->getFileManager();
3166 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3167}
3168
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003169unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3170 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003171 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003172 LOG_BAD_TU(TU);
3173 return 0;
3174 }
3175
3176 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return 0;
3178
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003179 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 FileEntry *FEnt = static_cast<FileEntry *>(file);
3181 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3182 .isFileMultipleIncludeGuarded(FEnt);
3183}
3184
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003185int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3186 if (!file || !outID)
3187 return 1;
3188
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003189 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003190 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3191 outID->data[0] = ID.getDevice();
3192 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003193 outID->data[2] = FEnt->getModificationTime();
3194 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003195}
3196
Guy Benyei11169dd2012-12-18 14:30:41 +00003197} // end: extern "C"
3198
3199//===----------------------------------------------------------------------===//
3200// CXCursor Operations.
3201//===----------------------------------------------------------------------===//
3202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203static const Decl *getDeclFromExpr(const Stmt *E) {
3204 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return getDeclFromExpr(CE->getSubExpr());
3206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003209 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003211 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003213 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 if (PRE->isExplicitProperty())
3215 return PRE->getExplicitProperty();
3216 // It could be messaging both getter and setter as in:
3217 // ++myobj.myprop;
3218 // in which case prefer to associate the setter since it is less obvious
3219 // from inspecting the source that the setter is going to get called.
3220 if (PRE->isMessagingSetter())
3221 return PRE->getImplicitPropertySetter();
3222 return PRE->getImplicitPropertyGetter();
3223 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003224 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003226 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 if (Expr *Src = OVE->getSourceExpr())
3228 return getDeclFromExpr(Src);
3229
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003230 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003232 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 if (!CE->isElidable())
3234 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003235 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 return OME->getMethodDecl();
3237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003238 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003240 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3242 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003243 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3245 isa<ParmVarDecl>(SizeOfPack->getPack()))
3246 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003247
3248 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003249}
3250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003251static SourceLocation getLocationFromExpr(const Expr *E) {
3252 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 return getLocationFromExpr(CE->getSubExpr());
3254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003255 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003257 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003259 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003261 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003263 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003265 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 return PropRef->getLocation();
3267
3268 return E->getLocStart();
3269}
3270
3271extern "C" {
3272
3273unsigned clang_visitChildren(CXCursor parent,
3274 CXCursorVisitor visitor,
3275 CXClientData client_data) {
3276 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3277 /*VisitPreprocessorLast=*/false);
3278 return CursorVis.VisitChildren(parent);
3279}
3280
3281#ifndef __has_feature
3282#define __has_feature(x) 0
3283#endif
3284#if __has_feature(blocks)
3285typedef enum CXChildVisitResult
3286 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3287
3288static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3289 CXClientData client_data) {
3290 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3291 return block(cursor, parent);
3292}
3293#else
3294// If we are compiled with a compiler that doesn't have native blocks support,
3295// define and call the block manually, so the
3296typedef struct _CXChildVisitResult
3297{
3298 void *isa;
3299 int flags;
3300 int reserved;
3301 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3302 CXCursor);
3303} *CXCursorVisitorBlock;
3304
3305static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3306 CXClientData client_data) {
3307 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3308 return block->invoke(block, cursor, parent);
3309}
3310#endif
3311
3312
3313unsigned clang_visitChildrenWithBlock(CXCursor parent,
3314 CXCursorVisitorBlock block) {
3315 return clang_visitChildren(parent, visitWithBlock, block);
3316}
3317
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003320 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003321
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003322 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003324 if (const ObjCPropertyImplDecl *PropImpl =
3325 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003331 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003332
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003333 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003336 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003339 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3341 // and returns different names. NamedDecl returns the class name and
3342 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003343 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344
3345 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003346 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
3348 SmallString<1024> S;
3349 llvm::raw_svector_ostream os(S);
3350 ND->printName(os);
3351
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353}
3354
3355CXString clang_getCursorSpelling(CXCursor C) {
3356 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003357 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003358
3359 if (clang_isReference(C.kind)) {
3360 switch (C.kind) {
3361 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003362 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003367 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
3369 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003370 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003372 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003375 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
3378 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003379 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 assert(Type && "Missing type decl");
3381
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 getAsString());
3384 }
3385 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003386 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 assert(Template && "Missing template decl");
3388
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003389 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 }
3391
3392 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003393 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 assert(NS && "Missing namespace decl");
3395
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398
3399 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003400 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 assert(Field && "Missing member decl");
3402
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003403 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 }
3405
3406 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003407 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 assert(Label && "Missing label");
3409
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003410 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
3413 case CXCursor_OverloadedDeclRef: {
3414 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3416 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003417 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003418 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003420 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003421 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 OverloadedTemplateStorage *Ovl
3423 = Storage.get<OverloadedTemplateStorage*>();
3424 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003425 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003426 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 }
3428
3429 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003430 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 assert(Var && "Missing variable decl");
3432
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
3435
3436 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003437 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439 }
3440
3441 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003442 const Expr *E = getCursorExpr(C);
3443
3444 if (C.kind == CXCursor_ObjCStringLiteral ||
3445 C.kind == CXCursor_StringLiteral) {
3446 const StringLiteral *SLit;
3447 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3448 SLit = OSL->getString();
3449 } else {
3450 SLit = cast<StringLiteral>(E);
3451 }
3452 SmallString<256> Buf;
3453 llvm::raw_svector_ostream OS(Buf);
3454 SLit->outputString(OS);
3455 return cxstring::createDup(OS.str());
3456 }
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (D)
3460 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003461 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 }
3463
3464 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003465 const Stmt *S = getCursorStmt(C);
3466 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003467 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003469 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 }
3471
3472 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003473 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 ->getNameStart());
3475
3476 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003477 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 ->getNameStart());
3479
3480 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003481 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003482
3483 if (clang_isDeclaration(C.kind))
3484 return getDeclSpelling(getCursorDecl(C));
3485
3486 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003487 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003488 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 }
3490
3491 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003492 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003493 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 }
3495
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003496 if (C.kind == CXCursor_PackedAttr) {
3497 return cxstring::createRef("packed");
3498 }
3499
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003500 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003501}
3502
3503CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3504 unsigned pieceIndex,
3505 unsigned options) {
3506 if (clang_Cursor_isNull(C))
3507 return clang_getNullRange();
3508
3509 ASTContext &Ctx = getCursorContext(C);
3510
3511 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003512 const Stmt *S = getCursorStmt(C);
3513 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 if (pieceIndex > 0)
3515 return clang_getNullRange();
3516 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3517 }
3518
3519 return clang_getNullRange();
3520 }
3521
3522 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003523 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3525 if (pieceIndex >= ME->getNumSelectorLocs())
3526 return clang_getNullRange();
3527 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3528 }
3529 }
3530
3531 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3532 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3535 if (pieceIndex >= MD->getNumSelectorLocs())
3536 return clang_getNullRange();
3537 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3538 }
3539 }
3540
3541 if (C.kind == CXCursor_ObjCCategoryDecl ||
3542 C.kind == CXCursor_ObjCCategoryImplDecl) {
3543 if (pieceIndex > 0)
3544 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3547 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3550 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3551 }
3552
3553 if (C.kind == CXCursor_ModuleImportDecl) {
3554 if (pieceIndex > 0)
3555 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const ImportDecl *ImportD =
3557 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3559 if (!Locs.empty())
3560 return cxloc::translateSourceRange(Ctx,
3561 SourceRange(Locs.front(), Locs.back()));
3562 }
3563 return clang_getNullRange();
3564 }
3565
3566 // FIXME: A CXCursor_InclusionDirective should give the location of the
3567 // filename, but we don't keep track of this.
3568
3569 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3570 // but we don't keep track of this.
3571
3572 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3573 // but we don't keep track of this.
3574
3575 // Default handling, give the location of the cursor.
3576
3577 if (pieceIndex > 0)
3578 return clang_getNullRange();
3579
3580 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3581 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3582 return cxloc::translateSourceRange(Ctx, Loc);
3583}
3584
3585CXString clang_getCursorDisplayName(CXCursor C) {
3586 if (!clang_isDeclaration(C.kind))
3587 return clang_getCursorSpelling(C);
3588
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003589 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003591 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
3593 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003594 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 D = FunTmpl->getTemplatedDecl();
3596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 SmallString<64> Str;
3599 llvm::raw_svector_ostream OS(Str);
3600 OS << *Function;
3601 if (Function->getPrimaryTemplate())
3602 OS << "<>";
3603 OS << "(";
3604 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3605 if (I)
3606 OS << ", ";
3607 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3608 }
3609
3610 if (Function->isVariadic()) {
3611 if (Function->getNumParams())
3612 OS << ", ";
3613 OS << "...";
3614 }
3615 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 }
3618
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003619 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 SmallString<64> Str;
3621 llvm::raw_svector_ostream OS(Str);
3622 OS << *ClassTemplate;
3623 OS << "<";
3624 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3625 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3626 if (I)
3627 OS << ", ";
3628
3629 NamedDecl *Param = Params->getParam(I);
3630 if (Param->getIdentifier()) {
3631 OS << Param->getIdentifier()->getName();
3632 continue;
3633 }
3634
3635 // There is no parameter name, which makes this tricky. Try to come up
3636 // with something useful that isn't too long.
3637 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3638 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3639 else if (NonTypeTemplateParmDecl *NTTP
3640 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3641 OS << NTTP->getType().getAsString(Policy);
3642 else
3643 OS << "template<...> class";
3644 }
3645
3646 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003647 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 }
3649
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003650 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3652 // If the type was explicitly written, use that.
3653 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003654 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003655
Benjamin Kramer9170e912013-02-22 15:46:01 +00003656 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 llvm::raw_svector_ostream OS(Str);
3658 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003659 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 ClassSpec->getTemplateArgs().data(),
3661 ClassSpec->getTemplateArgs().size(),
3662 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003663 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 }
3665
3666 return clang_getCursorSpelling(C);
3667}
3668
3669CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3670 switch (Kind) {
3671 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003799 case CXCursor_ObjCSelfExpr:
3800 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003917 case CXCursor_PackedAttr:
3918 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003919 case CXCursor_PureAttr:
3920 return cxstring::createRef("attribute(pure)");
3921 case CXCursor_ConstAttr:
3922 return cxstring::createRef("attribute(const)");
3923 case CXCursor_NoDuplicateAttr:
3924 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003925 case CXCursor_CUDAConstantAttr:
3926 return cxstring::createRef("attribute(constant)");
3927 case CXCursor_CUDADeviceAttr:
3928 return cxstring::createRef("attribute(device)");
3929 case CXCursor_CUDAGlobalAttr:
3930 return cxstring::createRef("attribute(global)");
3931 case CXCursor_CUDAHostAttr:
3932 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003981 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003982 return cxstring::createRef("OMPParallelDirective");
3983 case CXCursor_OMPSimdDirective:
3984 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003985 case CXCursor_OMPForDirective:
3986 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003987 case CXCursor_OMPSectionsDirective:
3988 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003989 case CXCursor_OMPSectionDirective:
3990 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003991 case CXCursor_OMPSingleDirective:
3992 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 }
3994
3995 llvm_unreachable("Unhandled CXCursorKind");
3996}
3997
3998struct GetCursorData {
3999 SourceLocation TokenBeginLoc;
4000 bool PointsAtMacroArgExpansion;
4001 bool VisitedObjCPropertyImplDecl;
4002 SourceLocation VisitedDeclaratorDeclStartLoc;
4003 CXCursor &BestCursor;
4004
4005 GetCursorData(SourceManager &SM,
4006 SourceLocation tokenBegin, CXCursor &outputCursor)
4007 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4008 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4009 VisitedObjCPropertyImplDecl = false;
4010 }
4011};
4012
4013static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4014 CXCursor parent,
4015 CXClientData client_data) {
4016 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4017 CXCursor *BestCursor = &Data->BestCursor;
4018
4019 // If we point inside a macro argument we should provide info of what the
4020 // token is so use the actual cursor, don't replace it with a macro expansion
4021 // cursor.
4022 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4023 return CXChildVisit_Recurse;
4024
4025 if (clang_isDeclaration(cursor.kind)) {
4026 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004027 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4029 if (MD->isImplicit())
4030 return CXChildVisit_Break;
4031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004032 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4034 // Check that when we have multiple @class references in the same line,
4035 // that later ones do not override the previous ones.
4036 // If we have:
4037 // @class Foo, Bar;
4038 // source ranges for both start at '@', so 'Bar' will end up overriding
4039 // 'Foo' even though the cursor location was at 'Foo'.
4040 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4041 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4044 if (PrevID != ID &&
4045 !PrevID->isThisDeclarationADefinition() &&
4046 !ID->isThisDeclarationADefinition())
4047 return CXChildVisit_Break;
4048 }
4049
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004050 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4052 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4053 // Check that when we have multiple declarators in the same line,
4054 // that later ones do not override the previous ones.
4055 // If we have:
4056 // int Foo, Bar;
4057 // source ranges for both start at 'int', so 'Bar' will end up overriding
4058 // 'Foo' even though the cursor location was at 'Foo'.
4059 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4060 return CXChildVisit_Break;
4061 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4062
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004063 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4065 (void)PropImp;
4066 // Check that when we have multiple @synthesize in the same line,
4067 // that later ones do not override the previous ones.
4068 // If we have:
4069 // @synthesize Foo, Bar;
4070 // source ranges for both start at '@', so 'Bar' will end up overriding
4071 // 'Foo' even though the cursor location was at 'Foo'.
4072 if (Data->VisitedObjCPropertyImplDecl)
4073 return CXChildVisit_Break;
4074 Data->VisitedObjCPropertyImplDecl = true;
4075 }
4076 }
4077
4078 if (clang_isExpression(cursor.kind) &&
4079 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004080 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 // Avoid having the cursor of an expression replace the declaration cursor
4082 // when the expression source range overlaps the declaration range.
4083 // This can happen for C++ constructor expressions whose range generally
4084 // include the variable declaration, e.g.:
4085 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4086 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4087 D->getLocation() == Data->TokenBeginLoc)
4088 return CXChildVisit_Break;
4089 }
4090 }
4091
4092 // If our current best cursor is the construction of a temporary object,
4093 // don't replace that cursor with a type reference, because we want
4094 // clang_getCursor() to point at the constructor.
4095 if (clang_isExpression(BestCursor->kind) &&
4096 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4097 cursor.kind == CXCursor_TypeRef) {
4098 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4099 // as having the actual point on the type reference.
4100 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4101 return CXChildVisit_Recurse;
4102 }
4103
4104 *BestCursor = cursor;
4105 return CXChildVisit_Recurse;
4106}
4107
4108CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004110 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004112 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004113
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004114 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4116
4117 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4118 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4119
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004120 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 CXFile SearchFile;
4122 unsigned SearchLine, SearchColumn;
4123 CXFile ResultFile;
4124 unsigned ResultLine, ResultColumn;
4125 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4126 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4127 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004128
4129 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4130 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004131 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004132 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 SearchFileName = clang_getFileName(SearchFile);
4134 ResultFileName = clang_getFileName(ResultFile);
4135 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4136 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004137 *Log << llvm::format("(%s:%d:%d) = %s",
4138 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4139 clang_getCString(KindSpelling))
4140 << llvm::format("(%s:%d:%d):%s%s",
4141 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4142 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 clang_disposeString(SearchFileName);
4144 clang_disposeString(ResultFileName);
4145 clang_disposeString(KindSpelling);
4146 clang_disposeString(USR);
4147
4148 CXCursor Definition = clang_getCursorDefinition(Result);
4149 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4150 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4151 CXString DefinitionKindSpelling
4152 = clang_getCursorKindSpelling(Definition.kind);
4153 CXFile DefinitionFile;
4154 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004155 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004156 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004158 *Log << llvm::format(" -> %s(%s:%d:%d)",
4159 clang_getCString(DefinitionKindSpelling),
4160 clang_getCString(DefinitionFileName),
4161 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 clang_disposeString(DefinitionFileName);
4163 clang_disposeString(DefinitionKindSpelling);
4164 }
4165 }
4166
4167 return Result;
4168}
4169
4170CXCursor clang_getNullCursor(void) {
4171 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4172}
4173
4174unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004175 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4176 // can't set consistently. For example, when visiting a DeclStmt we will set
4177 // it but we don't set it on the result of clang_getCursorDefinition for
4178 // a reference of the same declaration.
4179 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4180 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4181 // to provide that kind of info.
4182 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004183 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004184 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004185 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004186
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 return X == Y;
4188}
4189
4190unsigned clang_hashCursor(CXCursor C) {
4191 unsigned Index = 0;
4192 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4193 Index = 1;
4194
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004195 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 std::make_pair(C.kind, C.data[Index]));
4197}
4198
4199unsigned clang_isInvalid(enum CXCursorKind K) {
4200 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4201}
4202
4203unsigned clang_isDeclaration(enum CXCursorKind K) {
4204 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4205 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4206}
4207
4208unsigned clang_isReference(enum CXCursorKind K) {
4209 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4210}
4211
4212unsigned clang_isExpression(enum CXCursorKind K) {
4213 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4214}
4215
4216unsigned clang_isStatement(enum CXCursorKind K) {
4217 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4218}
4219
4220unsigned clang_isAttribute(enum CXCursorKind K) {
4221 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4222}
4223
4224unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4225 return K == CXCursor_TranslationUnit;
4226}
4227
4228unsigned clang_isPreprocessing(enum CXCursorKind K) {
4229 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4230}
4231
4232unsigned clang_isUnexposed(enum CXCursorKind K) {
4233 switch (K) {
4234 case CXCursor_UnexposedDecl:
4235 case CXCursor_UnexposedExpr:
4236 case CXCursor_UnexposedStmt:
4237 case CXCursor_UnexposedAttr:
4238 return true;
4239 default:
4240 return false;
4241 }
4242}
4243
4244CXCursorKind clang_getCursorKind(CXCursor C) {
4245 return C.kind;
4246}
4247
4248CXSourceLocation clang_getCursorLocation(CXCursor C) {
4249 if (clang_isReference(C.kind)) {
4250 switch (C.kind) {
4251 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004252 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 = getCursorObjCSuperClassRef(C);
4254 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4255 }
4256
4257 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004258 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 = getCursorObjCProtocolRef(C);
4260 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4261 }
4262
4263 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004264 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 = getCursorObjCClassRef(C);
4266 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4267 }
4268
4269 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004270 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4272 }
4273
4274 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004275 std::pair<const TemplateDecl *, SourceLocation> P =
4276 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4278 }
4279
4280 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004281 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4283 }
4284
4285 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004286 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4288 }
4289
4290 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004291 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4293 }
4294
4295 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004296 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 if (!BaseSpec)
4298 return clang_getNullLocation();
4299
4300 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4301 return cxloc::translateSourceLocation(getCursorContext(C),
4302 TSInfo->getTypeLoc().getBeginLoc());
4303
4304 return cxloc::translateSourceLocation(getCursorContext(C),
4305 BaseSpec->getLocStart());
4306 }
4307
4308 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004309 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4311 }
4312
4313 case CXCursor_OverloadedDeclRef:
4314 return cxloc::translateSourceLocation(getCursorContext(C),
4315 getCursorOverloadedDeclRef(C).second);
4316
4317 default:
4318 // FIXME: Need a way to enumerate all non-reference cases.
4319 llvm_unreachable("Missed a reference kind");
4320 }
4321 }
4322
4323 if (clang_isExpression(C.kind))
4324 return cxloc::translateSourceLocation(getCursorContext(C),
4325 getLocationFromExpr(getCursorExpr(C)));
4326
4327 if (clang_isStatement(C.kind))
4328 return cxloc::translateSourceLocation(getCursorContext(C),
4329 getCursorStmt(C)->getLocStart());
4330
4331 if (C.kind == CXCursor_PreprocessingDirective) {
4332 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4333 return cxloc::translateSourceLocation(getCursorContext(C), L);
4334 }
4335
4336 if (C.kind == CXCursor_MacroExpansion) {
4337 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004338 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 return cxloc::translateSourceLocation(getCursorContext(C), L);
4340 }
4341
4342 if (C.kind == CXCursor_MacroDefinition) {
4343 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4344 return cxloc::translateSourceLocation(getCursorContext(C), L);
4345 }
4346
4347 if (C.kind == CXCursor_InclusionDirective) {
4348 SourceLocation L
4349 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4350 return cxloc::translateSourceLocation(getCursorContext(C), L);
4351 }
4352
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004353 if (clang_isAttribute(C.kind)) {
4354 SourceLocation L
4355 = cxcursor::getCursorAttr(C)->getLocation();
4356 return cxloc::translateSourceLocation(getCursorContext(C), L);
4357 }
4358
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 if (!clang_isDeclaration(C.kind))
4360 return clang_getNullLocation();
4361
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004362 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 if (!D)
4364 return clang_getNullLocation();
4365
4366 SourceLocation Loc = D->getLocation();
4367 // FIXME: Multiple variables declared in a single declaration
4368 // currently lack the information needed to correctly determine their
4369 // ranges when accounting for the type-specifier. We use context
4370 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4371 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004372 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 if (!cxcursor::isFirstInDeclGroup(C))
4374 Loc = VD->getLocation();
4375 }
4376
4377 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004378 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 Loc = MD->getSelectorStartLoc();
4380
4381 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4382}
4383
4384} // end extern "C"
4385
4386CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4387 assert(TU);
4388
4389 // Guard against an invalid SourceLocation, or we may assert in one
4390 // of the following calls.
4391 if (SLoc.isInvalid())
4392 return clang_getNullCursor();
4393
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004394 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004395
4396 // Translate the given source location to make it point at the beginning of
4397 // the token under the cursor.
4398 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4399 CXXUnit->getASTContext().getLangOpts());
4400
4401 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4402 if (SLoc.isValid()) {
4403 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4404 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4405 /*VisitPreprocessorLast=*/true,
4406 /*VisitIncludedEntities=*/false,
4407 SourceLocation(SLoc));
4408 CursorVis.visitFileRegion();
4409 }
4410
4411 return Result;
4412}
4413
4414static SourceRange getRawCursorExtent(CXCursor C) {
4415 if (clang_isReference(C.kind)) {
4416 switch (C.kind) {
4417 case CXCursor_ObjCSuperClassRef:
4418 return getCursorObjCSuperClassRef(C).second;
4419
4420 case CXCursor_ObjCProtocolRef:
4421 return getCursorObjCProtocolRef(C).second;
4422
4423 case CXCursor_ObjCClassRef:
4424 return getCursorObjCClassRef(C).second;
4425
4426 case CXCursor_TypeRef:
4427 return getCursorTypeRef(C).second;
4428
4429 case CXCursor_TemplateRef:
4430 return getCursorTemplateRef(C).second;
4431
4432 case CXCursor_NamespaceRef:
4433 return getCursorNamespaceRef(C).second;
4434
4435 case CXCursor_MemberRef:
4436 return getCursorMemberRef(C).second;
4437
4438 case CXCursor_CXXBaseSpecifier:
4439 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4440
4441 case CXCursor_LabelRef:
4442 return getCursorLabelRef(C).second;
4443
4444 case CXCursor_OverloadedDeclRef:
4445 return getCursorOverloadedDeclRef(C).second;
4446
4447 case CXCursor_VariableRef:
4448 return getCursorVariableRef(C).second;
4449
4450 default:
4451 // FIXME: Need a way to enumerate all non-reference cases.
4452 llvm_unreachable("Missed a reference kind");
4453 }
4454 }
4455
4456 if (clang_isExpression(C.kind))
4457 return getCursorExpr(C)->getSourceRange();
4458
4459 if (clang_isStatement(C.kind))
4460 return getCursorStmt(C)->getSourceRange();
4461
4462 if (clang_isAttribute(C.kind))
4463 return getCursorAttr(C)->getRange();
4464
4465 if (C.kind == CXCursor_PreprocessingDirective)
4466 return cxcursor::getCursorPreprocessingDirective(C);
4467
4468 if (C.kind == CXCursor_MacroExpansion) {
4469 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004470 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 return TU->mapRangeFromPreamble(Range);
4472 }
4473
4474 if (C.kind == CXCursor_MacroDefinition) {
4475 ASTUnit *TU = getCursorASTUnit(C);
4476 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4477 return TU->mapRangeFromPreamble(Range);
4478 }
4479
4480 if (C.kind == CXCursor_InclusionDirective) {
4481 ASTUnit *TU = getCursorASTUnit(C);
4482 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4483 return TU->mapRangeFromPreamble(Range);
4484 }
4485
4486 if (C.kind == CXCursor_TranslationUnit) {
4487 ASTUnit *TU = getCursorASTUnit(C);
4488 FileID MainID = TU->getSourceManager().getMainFileID();
4489 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4490 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4491 return SourceRange(Start, End);
4492 }
4493
4494 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004495 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 if (!D)
4497 return SourceRange();
4498
4499 SourceRange R = D->getSourceRange();
4500 // FIXME: Multiple variables declared in a single declaration
4501 // currently lack the information needed to correctly determine their
4502 // ranges when accounting for the type-specifier. We use context
4503 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4504 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (!cxcursor::isFirstInDeclGroup(C))
4507 R.setBegin(VD->getLocation());
4508 }
4509 return R;
4510 }
4511 return SourceRange();
4512}
4513
4514/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4515/// the decl-specifier-seq for declarations.
4516static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4517 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 if (!D)
4520 return SourceRange();
4521
4522 SourceRange R = D->getSourceRange();
4523
4524 // Adjust the start of the location for declarations preceded by
4525 // declaration specifiers.
4526 SourceLocation StartLoc;
4527 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4528 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4529 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4532 StartLoc = TI->getTypeLoc().getLocStart();
4533 }
4534
4535 if (StartLoc.isValid() && R.getBegin().isValid() &&
4536 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4537 R.setBegin(StartLoc);
4538
4539 // FIXME: Multiple variables declared in a single declaration
4540 // currently lack the information needed to correctly determine their
4541 // ranges when accounting for the type-specifier. We use context
4542 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4543 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 if (!cxcursor::isFirstInDeclGroup(C))
4546 R.setBegin(VD->getLocation());
4547 }
4548
4549 return R;
4550 }
4551
4552 return getRawCursorExtent(C);
4553}
4554
4555extern "C" {
4556
4557CXSourceRange clang_getCursorExtent(CXCursor C) {
4558 SourceRange R = getRawCursorExtent(C);
4559 if (R.isInvalid())
4560 return clang_getNullRange();
4561
4562 return cxloc::translateSourceRange(getCursorContext(C), R);
4563}
4564
4565CXCursor clang_getCursorReferenced(CXCursor C) {
4566 if (clang_isInvalid(C.kind))
4567 return clang_getNullCursor();
4568
4569 CXTranslationUnit tu = getCursorTU(C);
4570 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004571 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 if (!D)
4573 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004574 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004576 if (const ObjCPropertyImplDecl *PropImpl =
4577 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4579 return MakeCXCursor(Property, tu);
4580
4581 return C;
4582 }
4583
4584 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004585 const Expr *E = getCursorExpr(C);
4586 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 if (D) {
4588 CXCursor declCursor = MakeCXCursor(D, tu);
4589 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4590 declCursor);
4591 return declCursor;
4592 }
4593
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 return MakeCursorOverloadedDeclRef(Ovl, tu);
4596
4597 return clang_getNullCursor();
4598 }
4599
4600 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004601 const Stmt *S = getCursorStmt(C);
4602 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 if (LabelDecl *label = Goto->getLabel())
4604 if (LabelStmt *labelS = label->getStmt())
4605 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4606
4607 return clang_getNullCursor();
4608 }
4609
4610 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004611 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 return MakeMacroDefinitionCursor(Def, tu);
4613 }
4614
4615 if (!clang_isReference(C.kind))
4616 return clang_getNullCursor();
4617
4618 switch (C.kind) {
4619 case CXCursor_ObjCSuperClassRef:
4620 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4621
4622 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004623 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4624 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 return MakeCXCursor(Def, tu);
4626
4627 return MakeCXCursor(Prot, tu);
4628 }
4629
4630 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004631 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4632 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 return MakeCXCursor(Def, tu);
4634
4635 return MakeCXCursor(Class, tu);
4636 }
4637
4638 case CXCursor_TypeRef:
4639 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4640
4641 case CXCursor_TemplateRef:
4642 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4643
4644 case CXCursor_NamespaceRef:
4645 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4646
4647 case CXCursor_MemberRef:
4648 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4649
4650 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004651 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4653 tu ));
4654 }
4655
4656 case CXCursor_LabelRef:
4657 // FIXME: We end up faking the "parent" declaration here because we
4658 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004659 return MakeCXCursor(getCursorLabelRef(C).first,
4660 cxtu::getASTUnit(tu)->getASTContext()
4661 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 tu);
4663
4664 case CXCursor_OverloadedDeclRef:
4665 return C;
4666
4667 case CXCursor_VariableRef:
4668 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4669
4670 default:
4671 // We would prefer to enumerate all non-reference cursor kinds here.
4672 llvm_unreachable("Unhandled reference cursor kind");
4673 }
4674}
4675
4676CXCursor clang_getCursorDefinition(CXCursor C) {
4677 if (clang_isInvalid(C.kind))
4678 return clang_getNullCursor();
4679
4680 CXTranslationUnit TU = getCursorTU(C);
4681
4682 bool WasReference = false;
4683 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4684 C = clang_getCursorReferenced(C);
4685 WasReference = true;
4686 }
4687
4688 if (C.kind == CXCursor_MacroExpansion)
4689 return clang_getCursorReferenced(C);
4690
4691 if (!clang_isDeclaration(C.kind))
4692 return clang_getNullCursor();
4693
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 if (!D)
4696 return clang_getNullCursor();
4697
4698 switch (D->getKind()) {
4699 // Declaration kinds that don't really separate the notions of
4700 // declaration and definition.
4701 case Decl::Namespace:
4702 case Decl::Typedef:
4703 case Decl::TypeAlias:
4704 case Decl::TypeAliasTemplate:
4705 case Decl::TemplateTypeParm:
4706 case Decl::EnumConstant:
4707 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004708 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case Decl::IndirectField:
4710 case Decl::ObjCIvar:
4711 case Decl::ObjCAtDefsField:
4712 case Decl::ImplicitParam:
4713 case Decl::ParmVar:
4714 case Decl::NonTypeTemplateParm:
4715 case Decl::TemplateTemplateParm:
4716 case Decl::ObjCCategoryImpl:
4717 case Decl::ObjCImplementation:
4718 case Decl::AccessSpec:
4719 case Decl::LinkageSpec:
4720 case Decl::ObjCPropertyImpl:
4721 case Decl::FileScopeAsm:
4722 case Decl::StaticAssert:
4723 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004724 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case Decl::Label: // FIXME: Is this right??
4726 case Decl::ClassScopeFunctionSpecialization:
4727 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004728 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 return C;
4730
4731 // Declaration kinds that don't make any sense here, but are
4732 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004733 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case Decl::TranslationUnit:
4735 break;
4736
4737 // Declaration kinds for which the definition is not resolvable.
4738 case Decl::UnresolvedUsingTypename:
4739 case Decl::UnresolvedUsingValue:
4740 break;
4741
4742 case Decl::UsingDirective:
4743 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4744 TU);
4745
4746 case Decl::NamespaceAlias:
4747 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4748
4749 case Decl::Enum:
4750 case Decl::Record:
4751 case Decl::CXXRecord:
4752 case Decl::ClassTemplateSpecialization:
4753 case Decl::ClassTemplatePartialSpecialization:
4754 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4755 return MakeCXCursor(Def, TU);
4756 return clang_getNullCursor();
4757
4758 case Decl::Function:
4759 case Decl::CXXMethod:
4760 case Decl::CXXConstructor:
4761 case Decl::CXXDestructor:
4762 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004763 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004765 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 return clang_getNullCursor();
4767 }
4768
Larisse Voufo39a1e502013-08-06 01:03:05 +00004769 case Decl::Var:
4770 case Decl::VarTemplateSpecialization:
4771 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 return MakeCXCursor(Def, TU);
4775 return clang_getNullCursor();
4776 }
4777
4778 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004779 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4781 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4782 return clang_getNullCursor();
4783 }
4784
4785 case Decl::ClassTemplate: {
4786 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4787 ->getDefinition())
4788 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4789 TU);
4790 return clang_getNullCursor();
4791 }
4792
Larisse Voufo39a1e502013-08-06 01:03:05 +00004793 case Decl::VarTemplate: {
4794 if (VarDecl *Def =
4795 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4796 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4797 return clang_getNullCursor();
4798 }
4799
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 case Decl::Using:
4801 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4802 D->getLocation(), TU);
4803
4804 case Decl::UsingShadow:
4805 return clang_getCursorDefinition(
4806 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4807 TU));
4808
4809 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004810 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 if (Method->isThisDeclarationADefinition())
4812 return C;
4813
4814 // Dig out the method definition in the associated
4815 // @implementation, if we have it.
4816 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4819 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4820 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4821 Method->isInstanceMethod()))
4822 if (Def->isThisDeclarationADefinition())
4823 return MakeCXCursor(Def, TU);
4824
4825 return clang_getNullCursor();
4826 }
4827
4828 case Decl::ObjCCategory:
4829 if (ObjCCategoryImplDecl *Impl
4830 = cast<ObjCCategoryDecl>(D)->getImplementation())
4831 return MakeCXCursor(Impl, TU);
4832 return clang_getNullCursor();
4833
4834 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 return MakeCXCursor(Def, TU);
4837 return clang_getNullCursor();
4838
4839 case Decl::ObjCInterface: {
4840 // There are two notions of a "definition" for an Objective-C
4841 // class: the interface and its implementation. When we resolved a
4842 // reference to an Objective-C class, produce the @interface as
4843 // the definition; when we were provided with the interface,
4844 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004845 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004847 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 return MakeCXCursor(Def, TU);
4849 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4850 return MakeCXCursor(Impl, TU);
4851 return clang_getNullCursor();
4852 }
4853
4854 case Decl::ObjCProperty:
4855 // FIXME: We don't really know where to find the
4856 // ObjCPropertyImplDecls that implement this property.
4857 return clang_getNullCursor();
4858
4859 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004862 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 return MakeCXCursor(Def, TU);
4864
4865 return clang_getNullCursor();
4866
4867 case Decl::Friend:
4868 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4869 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4870 return clang_getNullCursor();
4871
4872 case Decl::FriendTemplate:
4873 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4874 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4875 return clang_getNullCursor();
4876 }
4877
4878 return clang_getNullCursor();
4879}
4880
4881unsigned clang_isCursorDefinition(CXCursor C) {
4882 if (!clang_isDeclaration(C.kind))
4883 return 0;
4884
4885 return clang_getCursorDefinition(C) == C;
4886}
4887
4888CXCursor clang_getCanonicalCursor(CXCursor C) {
4889 if (!clang_isDeclaration(C.kind))
4890 return C;
4891
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 if (const Decl *D = getCursorDecl(C)) {
4893 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4895 return MakeCXCursor(CatD, getCursorTU(C));
4896
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004897 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4898 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 return MakeCXCursor(IFD, getCursorTU(C));
4900
4901 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4902 }
4903
4904 return C;
4905}
4906
4907int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4908 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4909}
4910
4911unsigned clang_getNumOverloadedDecls(CXCursor C) {
4912 if (C.kind != CXCursor_OverloadedDeclRef)
4913 return 0;
4914
4915 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 return E->getNumDecls();
4918
4919 if (OverloadedTemplateStorage *S
4920 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4921 return S->size();
4922
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004923 const Decl *D = Storage.get<const Decl *>();
4924 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 return Using->shadow_size();
4926
4927 return 0;
4928}
4929
4930CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4931 if (cursor.kind != CXCursor_OverloadedDeclRef)
4932 return clang_getNullCursor();
4933
4934 if (index >= clang_getNumOverloadedDecls(cursor))
4935 return clang_getNullCursor();
4936
4937 CXTranslationUnit TU = getCursorTU(cursor);
4938 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004939 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 return MakeCXCursor(E->decls_begin()[index], TU);
4941
4942 if (OverloadedTemplateStorage *S
4943 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4944 return MakeCXCursor(S->begin()[index], TU);
4945
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 const Decl *D = Storage.get<const Decl *>();
4947 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 // FIXME: This is, unfortunately, linear time.
4949 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4950 std::advance(Pos, index);
4951 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4952 }
4953
4954 return clang_getNullCursor();
4955}
4956
4957void clang_getDefinitionSpellingAndExtent(CXCursor C,
4958 const char **startBuf,
4959 const char **endBuf,
4960 unsigned *startLine,
4961 unsigned *startColumn,
4962 unsigned *endLine,
4963 unsigned *endColumn) {
4964 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004965 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4967
4968 SourceManager &SM = FD->getASTContext().getSourceManager();
4969 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4970 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4971 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4972 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4973 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4974 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4975}
4976
4977
4978CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4979 unsigned PieceIndex) {
4980 RefNamePieces Pieces;
4981
4982 switch (C.kind) {
4983 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004984 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4986 E->getQualifierLoc().getSourceRange());
4987 break;
4988
4989 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004990 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4992 E->getQualifierLoc().getSourceRange(),
4993 E->getOptionalExplicitTemplateArgs());
4994 break;
4995
4996 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004997 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004999 const Expr *Callee = OCE->getCallee();
5000 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 Callee = ICE->getSubExpr();
5002
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005003 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5005 DRE->getQualifierLoc().getSourceRange());
5006 }
5007 break;
5008
5009 default:
5010 break;
5011 }
5012
5013 if (Pieces.empty()) {
5014 if (PieceIndex == 0)
5015 return clang_getCursorExtent(C);
5016 } else if (PieceIndex < Pieces.size()) {
5017 SourceRange R = Pieces[PieceIndex];
5018 if (R.isValid())
5019 return cxloc::translateSourceRange(getCursorContext(C), R);
5020 }
5021
5022 return clang_getNullRange();
5023}
5024
5025void clang_enableStackTraces(void) {
5026 llvm::sys::PrintStackTraceOnErrorSignal();
5027}
5028
5029void clang_executeOnThread(void (*fn)(void*), void *user_data,
5030 unsigned stack_size) {
5031 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5032}
5033
5034} // end: extern "C"
5035
5036//===----------------------------------------------------------------------===//
5037// Token-based Operations.
5038//===----------------------------------------------------------------------===//
5039
5040/* CXToken layout:
5041 * int_data[0]: a CXTokenKind
5042 * int_data[1]: starting token location
5043 * int_data[2]: token length
5044 * int_data[3]: reserved
5045 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5046 * otherwise unused.
5047 */
5048extern "C" {
5049
5050CXTokenKind clang_getTokenKind(CXToken CXTok) {
5051 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5052}
5053
5054CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5055 switch (clang_getTokenKind(CXTok)) {
5056 case CXToken_Identifier:
5057 case CXToken_Keyword:
5058 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005059 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 ->getNameStart());
5061
5062 case CXToken_Literal: {
5063 // We have stashed the starting pointer in the ptr_data field. Use it.
5064 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005065 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 }
5067
5068 case CXToken_Punctuation:
5069 case CXToken_Comment:
5070 break;
5071 }
5072
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005073 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005074 LOG_BAD_TU(TU);
5075 return cxstring::createEmpty();
5076 }
5077
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 // We have to find the starting buffer pointer the hard way, by
5079 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005080 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005082 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005083
5084 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5085 std::pair<FileID, unsigned> LocInfo
5086 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5087 bool Invalid = false;
5088 StringRef Buffer
5089 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5090 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005091 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005092
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005093 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005094}
5095
5096CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005097 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005098 LOG_BAD_TU(TU);
5099 return clang_getNullLocation();
5100 }
5101
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005102 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 if (!CXXUnit)
5104 return clang_getNullLocation();
5105
5106 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5107 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5108}
5109
5110CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005111 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005112 LOG_BAD_TU(TU);
5113 return clang_getNullRange();
5114 }
5115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005116 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 if (!CXXUnit)
5118 return clang_getNullRange();
5119
5120 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5121 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5122}
5123
5124static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5125 SmallVectorImpl<CXToken> &CXTokens) {
5126 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5127 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005128 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005130 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005131
5132 // Cannot tokenize across files.
5133 if (BeginLocInfo.first != EndLocInfo.first)
5134 return;
5135
5136 // Create a lexer
5137 bool Invalid = false;
5138 StringRef Buffer
5139 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5140 if (Invalid)
5141 return;
5142
5143 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5144 CXXUnit->getASTContext().getLangOpts(),
5145 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5146 Lex.SetCommentRetentionState(true);
5147
5148 // Lex tokens until we hit the end of the range.
5149 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5150 Token Tok;
5151 bool previousWasAt = false;
5152 do {
5153 // Lex the next token
5154 Lex.LexFromRawLexer(Tok);
5155 if (Tok.is(tok::eof))
5156 break;
5157
5158 // Initialize the CXToken.
5159 CXToken CXTok;
5160
5161 // - Common fields
5162 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5163 CXTok.int_data[2] = Tok.getLength();
5164 CXTok.int_data[3] = 0;
5165
5166 // - Kind-specific fields
5167 if (Tok.isLiteral()) {
5168 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005169 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 } else if (Tok.is(tok::raw_identifier)) {
5171 // Lookup the identifier to determine whether we have a keyword.
5172 IdentifierInfo *II
5173 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5174
5175 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5176 CXTok.int_data[0] = CXToken_Keyword;
5177 }
5178 else {
5179 CXTok.int_data[0] = Tok.is(tok::identifier)
5180 ? CXToken_Identifier
5181 : CXToken_Keyword;
5182 }
5183 CXTok.ptr_data = II;
5184 } else if (Tok.is(tok::comment)) {
5185 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005186 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 } else {
5188 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005189 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 }
5191 CXTokens.push_back(CXTok);
5192 previousWasAt = Tok.is(tok::at);
5193 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5194}
5195
5196void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5197 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005198 LOG_FUNC_SECTION {
5199 *Log << TU << ' ' << Range;
5200 }
5201
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005203 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 if (NumTokens)
5205 *NumTokens = 0;
5206
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005207 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005208 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005209 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005210 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005211
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005212 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 if (!CXXUnit || !Tokens || !NumTokens)
5214 return;
5215
5216 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5217
5218 SourceRange R = cxloc::translateCXSourceRange(Range);
5219 if (R.isInvalid())
5220 return;
5221
5222 SmallVector<CXToken, 32> CXTokens;
5223 getTokens(CXXUnit, R, CXTokens);
5224
5225 if (CXTokens.empty())
5226 return;
5227
5228 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5229 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5230 *NumTokens = CXTokens.size();
5231}
5232
5233void clang_disposeTokens(CXTranslationUnit TU,
5234 CXToken *Tokens, unsigned NumTokens) {
5235 free(Tokens);
5236}
5237
5238} // end: extern "C"
5239
5240//===----------------------------------------------------------------------===//
5241// Token annotation APIs.
5242//===----------------------------------------------------------------------===//
5243
Guy Benyei11169dd2012-12-18 14:30:41 +00005244static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5245 CXCursor parent,
5246 CXClientData client_data);
5247static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5248 CXClientData client_data);
5249
5250namespace {
5251class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 CXToken *Tokens;
5253 CXCursor *Cursors;
5254 unsigned NumTokens;
5255 unsigned TokIdx;
5256 unsigned PreprocessingTokIdx;
5257 CursorVisitor AnnotateVis;
5258 SourceManager &SrcMgr;
5259 bool HasContextSensitiveKeywords;
5260
5261 struct PostChildrenInfo {
5262 CXCursor Cursor;
5263 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005264 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 unsigned BeforeChildrenTokenIdx;
5266 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005267 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005268
5269 CXToken &getTok(unsigned Idx) {
5270 assert(Idx < NumTokens);
5271 return Tokens[Idx];
5272 }
5273 const CXToken &getTok(unsigned Idx) const {
5274 assert(Idx < NumTokens);
5275 return Tokens[Idx];
5276 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 bool MoreTokens() const { return TokIdx < NumTokens; }
5278 unsigned NextToken() const { return TokIdx; }
5279 void AdvanceToken() { ++TokIdx; }
5280 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005281 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 }
5283 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005284 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 }
5286 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005287 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 }
5289
5290 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005291 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 SourceRange);
5293
5294public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005295 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005296 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005297 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005299 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 AnnotateTokensVisitor, this,
5301 /*VisitPreprocessorLast=*/true,
5302 /*VisitIncludedEntities=*/false,
5303 RegionOfInterest,
5304 /*VisitDeclsOnly=*/false,
5305 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005306 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 HasContextSensitiveKeywords(false) { }
5308
5309 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5310 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5311 bool postVisitChildren(CXCursor cursor);
5312 void AnnotateTokens();
5313
5314 /// \brief Determine whether the annotator saw any cursors that have
5315 /// context-sensitive keywords.
5316 bool hasContextSensitiveKeywords() const {
5317 return HasContextSensitiveKeywords;
5318 }
5319
5320 ~AnnotateTokensWorker() {
5321 assert(PostChildrenInfos.empty());
5322 }
5323};
5324}
5325
5326void AnnotateTokensWorker::AnnotateTokens() {
5327 // Walk the AST within the region of interest, annotating tokens
5328 // along the way.
5329 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005330}
Guy Benyei11169dd2012-12-18 14:30:41 +00005331
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005332static inline void updateCursorAnnotation(CXCursor &Cursor,
5333 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005334 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005336 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005337}
5338
5339/// \brief It annotates and advances tokens with a cursor until the comparison
5340//// between the cursor location and the source range is the same as
5341/// \arg compResult.
5342///
5343/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5344/// Pass RangeOverlap to annotate tokens inside a range.
5345void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5346 RangeComparisonResult compResult,
5347 SourceRange range) {
5348 while (MoreTokens()) {
5349 const unsigned I = NextToken();
5350 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005351 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5352 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005353
5354 SourceLocation TokLoc = GetTokenLoc(I);
5355 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005356 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 AdvanceToken();
5358 continue;
5359 }
5360 break;
5361 }
5362}
5363
5364/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005365/// \returns true if it advanced beyond all macro tokens, false otherwise.
5366bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 CXCursor updateC,
5368 RangeComparisonResult compResult,
5369 SourceRange range) {
5370 assert(MoreTokens());
5371 assert(isFunctionMacroToken(NextToken()) &&
5372 "Should be called only for macro arg tokens");
5373
5374 // This works differently than annotateAndAdvanceTokens; because expanded
5375 // macro arguments can have arbitrary translation-unit source order, we do not
5376 // advance the token index one by one until a token fails the range test.
5377 // We only advance once past all of the macro arg tokens if all of them
5378 // pass the range test. If one of them fails we keep the token index pointing
5379 // at the start of the macro arg tokens so that the failing token will be
5380 // annotated by a subsequent annotation try.
5381
5382 bool atLeastOneCompFail = false;
5383
5384 unsigned I = NextToken();
5385 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5386 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5387 if (TokLoc.isFileID())
5388 continue; // not macro arg token, it's parens or comma.
5389 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5390 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5391 Cursors[I] = updateC;
5392 } else
5393 atLeastOneCompFail = true;
5394 }
5395
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005396 if (atLeastOneCompFail)
5397 return false;
5398
5399 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5400 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005401}
5402
5403enum CXChildVisitResult
5404AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 SourceRange cursorRange = getRawCursorExtent(cursor);
5406 if (cursorRange.isInvalid())
5407 return CXChildVisit_Recurse;
5408
5409 if (!HasContextSensitiveKeywords) {
5410 // Objective-C properties can have context-sensitive keywords.
5411 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005412 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5414 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5415 }
5416 // Objective-C methods can have context-sensitive keywords.
5417 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5418 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005419 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5421 if (Method->getObjCDeclQualifier())
5422 HasContextSensitiveKeywords = true;
5423 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005424 for (const auto *P : Method->params()) {
5425 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 HasContextSensitiveKeywords = true;
5427 break;
5428 }
5429 }
5430 }
5431 }
5432 }
5433 // C++ methods can have context-sensitive keywords.
5434 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005435 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5437 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5438 HasContextSensitiveKeywords = true;
5439 }
5440 }
5441 // C++ classes can have context-sensitive keywords.
5442 else if (cursor.kind == CXCursor_StructDecl ||
5443 cursor.kind == CXCursor_ClassDecl ||
5444 cursor.kind == CXCursor_ClassTemplate ||
5445 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005446 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 if (D->hasAttr<FinalAttr>())
5448 HasContextSensitiveKeywords = true;
5449 }
5450 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005451
5452 // Don't override a property annotation with its getter/setter method.
5453 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5454 parent.kind == CXCursor_ObjCPropertyDecl)
5455 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005456
5457 if (clang_isPreprocessing(cursor.kind)) {
5458 // Items in the preprocessing record are kept separate from items in
5459 // declarations, so we keep a separate token index.
5460 unsigned SavedTokIdx = TokIdx;
5461 TokIdx = PreprocessingTokIdx;
5462
5463 // Skip tokens up until we catch up to the beginning of the preprocessing
5464 // entry.
5465 while (MoreTokens()) {
5466 const unsigned I = NextToken();
5467 SourceLocation TokLoc = GetTokenLoc(I);
5468 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5469 case RangeBefore:
5470 AdvanceToken();
5471 continue;
5472 case RangeAfter:
5473 case RangeOverlap:
5474 break;
5475 }
5476 break;
5477 }
5478
5479 // Look at all of the tokens within this range.
5480 while (MoreTokens()) {
5481 const unsigned I = NextToken();
5482 SourceLocation TokLoc = GetTokenLoc(I);
5483 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5484 case RangeBefore:
5485 llvm_unreachable("Infeasible");
5486 case RangeAfter:
5487 break;
5488 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005489 // For macro expansions, just note where the beginning of the macro
5490 // expansion occurs.
5491 if (cursor.kind == CXCursor_MacroExpansion) {
5492 if (TokLoc == cursorRange.getBegin())
5493 Cursors[I] = cursor;
5494 AdvanceToken();
5495 break;
5496 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005497 // We may have already annotated macro names inside macro definitions.
5498 if (Cursors[I].kind != CXCursor_MacroExpansion)
5499 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 continue;
5502 }
5503 break;
5504 }
5505
5506 // Save the preprocessing token index; restore the non-preprocessing
5507 // token index.
5508 PreprocessingTokIdx = TokIdx;
5509 TokIdx = SavedTokIdx;
5510 return CXChildVisit_Recurse;
5511 }
5512
5513 if (cursorRange.isInvalid())
5514 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005515
5516 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 const enum CXCursorKind K = clang_getCursorKind(parent);
5519 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005520 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5521 // Attributes are annotated out-of-order, skip tokens until we reach it.
5522 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 ? clang_getNullCursor() : parent;
5524
5525 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5526
5527 // Avoid having the cursor of an expression "overwrite" the annotation of the
5528 // variable declaration that it belongs to.
5529 // This can happen for C++ constructor expressions whose range generally
5530 // include the variable declaration, e.g.:
5531 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005532 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005533 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005534 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 const unsigned I = NextToken();
5536 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5537 E->getLocStart() == D->getLocation() &&
5538 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005539 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005540 AdvanceToken();
5541 }
5542 }
5543 }
5544
5545 // Before recursing into the children keep some state that we are going
5546 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5547 // extra work after the child nodes are visited.
5548 // Note that we don't call VisitChildren here to avoid traversing statements
5549 // code-recursively which can blow the stack.
5550
5551 PostChildrenInfo Info;
5552 Info.Cursor = cursor;
5553 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005554 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 Info.BeforeChildrenTokenIdx = NextToken();
5556 PostChildrenInfos.push_back(Info);
5557
5558 return CXChildVisit_Recurse;
5559}
5560
5561bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5562 if (PostChildrenInfos.empty())
5563 return false;
5564 const PostChildrenInfo &Info = PostChildrenInfos.back();
5565 if (!clang_equalCursors(Info.Cursor, cursor))
5566 return false;
5567
5568 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5569 const unsigned AfterChildren = NextToken();
5570 SourceRange cursorRange = Info.CursorRange;
5571
5572 // Scan the tokens that are at the end of the cursor, but are not captured
5573 // but the child cursors.
5574 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5575
5576 // Scan the tokens that are at the beginning of the cursor, but are not
5577 // capture by the child cursors.
5578 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5579 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5580 break;
5581
5582 Cursors[I] = cursor;
5583 }
5584
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005585 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5586 // encountered the attribute cursor.
5587 if (clang_isAttribute(cursor.kind))
5588 TokIdx = Info.BeforeReachingCursorIdx;
5589
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 PostChildrenInfos.pop_back();
5591 return false;
5592}
5593
5594static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5595 CXCursor parent,
5596 CXClientData client_data) {
5597 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5598}
5599
5600static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5601 CXClientData client_data) {
5602 return static_cast<AnnotateTokensWorker*>(client_data)->
5603 postVisitChildren(cursor);
5604}
5605
5606namespace {
5607
5608/// \brief Uses the macro expansions in the preprocessing record to find
5609/// and mark tokens that are macro arguments. This info is used by the
5610/// AnnotateTokensWorker.
5611class MarkMacroArgTokensVisitor {
5612 SourceManager &SM;
5613 CXToken *Tokens;
5614 unsigned NumTokens;
5615 unsigned CurIdx;
5616
5617public:
5618 MarkMacroArgTokensVisitor(SourceManager &SM,
5619 CXToken *tokens, unsigned numTokens)
5620 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5621
5622 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5623 if (cursor.kind != CXCursor_MacroExpansion)
5624 return CXChildVisit_Continue;
5625
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005626 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 if (macroRange.getBegin() == macroRange.getEnd())
5628 return CXChildVisit_Continue; // it's not a function macro.
5629
5630 for (; CurIdx < NumTokens; ++CurIdx) {
5631 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5632 macroRange.getBegin()))
5633 break;
5634 }
5635
5636 if (CurIdx == NumTokens)
5637 return CXChildVisit_Break;
5638
5639 for (; CurIdx < NumTokens; ++CurIdx) {
5640 SourceLocation tokLoc = getTokenLoc(CurIdx);
5641 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5642 break;
5643
5644 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5645 }
5646
5647 if (CurIdx == NumTokens)
5648 return CXChildVisit_Break;
5649
5650 return CXChildVisit_Continue;
5651 }
5652
5653private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005654 CXToken &getTok(unsigned Idx) {
5655 assert(Idx < NumTokens);
5656 return Tokens[Idx];
5657 }
5658 const CXToken &getTok(unsigned Idx) const {
5659 assert(Idx < NumTokens);
5660 return Tokens[Idx];
5661 }
5662
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005664 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 }
5666
5667 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5668 // The third field is reserved and currently not used. Use it here
5669 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005670 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 }
5672};
5673
5674} // end anonymous namespace
5675
5676static CXChildVisitResult
5677MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5678 CXClientData client_data) {
5679 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5680 parent);
5681}
5682
5683namespace {
5684 struct clang_annotateTokens_Data {
5685 CXTranslationUnit TU;
5686 ASTUnit *CXXUnit;
5687 CXToken *Tokens;
5688 unsigned NumTokens;
5689 CXCursor *Cursors;
5690 };
5691}
5692
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005693/// \brief Used by \c annotatePreprocessorTokens.
5694/// \returns true if lexing was finished, false otherwise.
5695static bool lexNext(Lexer &Lex, Token &Tok,
5696 unsigned &NextIdx, unsigned NumTokens) {
5697 if (NextIdx >= NumTokens)
5698 return true;
5699
5700 ++NextIdx;
5701 Lex.LexFromRawLexer(Tok);
5702 if (Tok.is(tok::eof))
5703 return true;
5704
5705 return false;
5706}
5707
Guy Benyei11169dd2012-12-18 14:30:41 +00005708static void annotatePreprocessorTokens(CXTranslationUnit TU,
5709 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005710 CXCursor *Cursors,
5711 CXToken *Tokens,
5712 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005713 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005714
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005715 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5717 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005718 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005720 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005721
5722 if (BeginLocInfo.first != EndLocInfo.first)
5723 return;
5724
5725 StringRef Buffer;
5726 bool Invalid = false;
5727 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5728 if (Buffer.empty() || Invalid)
5729 return;
5730
5731 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5732 CXXUnit->getASTContext().getLangOpts(),
5733 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5734 Buffer.end());
5735 Lex.SetCommentRetentionState(true);
5736
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005737 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 // Lex tokens in raw mode until we hit the end of the range, to avoid
5739 // entering #includes or expanding macros.
5740 while (true) {
5741 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005742 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5743 break;
5744 unsigned TokIdx = NextIdx-1;
5745 assert(Tok.getLocation() ==
5746 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005747
5748 reprocess:
5749 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005750 // We have found a preprocessing directive. Annotate the tokens
5751 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 //
5753 // FIXME: Some simple tests here could identify macro definitions and
5754 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005755
5756 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005757 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5758 break;
5759
Craig Topper69186e72014-06-08 08:38:04 +00005760 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005761 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005762 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5763 break;
5764
5765 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005766 IdentifierInfo &II =
5767 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005768 SourceLocation MappedTokLoc =
5769 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5770 MI = getMacroInfo(II, MappedTokLoc, TU);
5771 }
5772 }
5773
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005774 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005776 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5777 finished = true;
5778 break;
5779 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005780 // If we are in a macro definition, check if the token was ever a
5781 // macro name and annotate it if that's the case.
5782 if (MI) {
5783 SourceLocation SaveLoc = Tok.getLocation();
5784 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5785 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5786 Tok.setLocation(SaveLoc);
5787 if (MacroDef)
5788 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5789 Tok.getLocation(), TU);
5790 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005791 } while (!Tok.isAtStartOfLine());
5792
5793 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5794 assert(TokIdx <= LastIdx);
5795 SourceLocation EndLoc =
5796 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5797 CXCursor Cursor =
5798 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5799
5800 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005801 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005802
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005803 if (finished)
5804 break;
5805 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 }
5808}
5809
5810// This gets run a separate thread to avoid stack blowout.
5811static void clang_annotateTokensImpl(void *UserData) {
5812 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5813 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5814 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5815 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5816 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5817
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005818 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5820 setThreadBackgroundPriority();
5821
5822 // Determine the region of interest, which contains all of the tokens.
5823 SourceRange RegionOfInterest;
5824 RegionOfInterest.setBegin(
5825 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5826 RegionOfInterest.setEnd(
5827 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5828 Tokens[NumTokens-1])));
5829
Guy Benyei11169dd2012-12-18 14:30:41 +00005830 // Relex the tokens within the source range to look for preprocessing
5831 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005832 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005833
5834 // If begin location points inside a macro argument, set it to the expansion
5835 // location so we can have the full context when annotating semantically.
5836 {
5837 SourceManager &SM = CXXUnit->getSourceManager();
5838 SourceLocation Loc =
5839 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5840 if (Loc.isMacroID())
5841 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5842 }
5843
Guy Benyei11169dd2012-12-18 14:30:41 +00005844 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5845 // Search and mark tokens that are macro argument expansions.
5846 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5847 Tokens, NumTokens);
5848 CursorVisitor MacroArgMarker(TU,
5849 MarkMacroArgTokensVisitorDelegate, &Visitor,
5850 /*VisitPreprocessorLast=*/true,
5851 /*VisitIncludedEntities=*/false,
5852 RegionOfInterest);
5853 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5854 }
5855
5856 // Annotate all of the source locations in the region of interest that map to
5857 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005858 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005859
5860 // FIXME: We use a ridiculous stack size here because the data-recursion
5861 // algorithm uses a large stack frame than the non-data recursive version,
5862 // and AnnotationTokensWorker currently transforms the data-recursion
5863 // algorithm back into a traditional recursion by explicitly calling
5864 // VisitChildren(). We will need to remove this explicit recursive call.
5865 W.AnnotateTokens();
5866
5867 // If we ran into any entities that involve context-sensitive keywords,
5868 // take another pass through the tokens to mark them as such.
5869 if (W.hasContextSensitiveKeywords()) {
5870 for (unsigned I = 0; I != NumTokens; ++I) {
5871 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5872 continue;
5873
5874 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5875 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005876 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5878 if (Property->getPropertyAttributesAsWritten() != 0 &&
5879 llvm::StringSwitch<bool>(II->getName())
5880 .Case("readonly", true)
5881 .Case("assign", true)
5882 .Case("unsafe_unretained", true)
5883 .Case("readwrite", true)
5884 .Case("retain", true)
5885 .Case("copy", true)
5886 .Case("nonatomic", true)
5887 .Case("atomic", true)
5888 .Case("getter", true)
5889 .Case("setter", true)
5890 .Case("strong", true)
5891 .Case("weak", true)
5892 .Default(false))
5893 Tokens[I].int_data[0] = CXToken_Keyword;
5894 }
5895 continue;
5896 }
5897
5898 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5899 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5900 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5901 if (llvm::StringSwitch<bool>(II->getName())
5902 .Case("in", true)
5903 .Case("out", true)
5904 .Case("inout", true)
5905 .Case("oneway", true)
5906 .Case("bycopy", true)
5907 .Case("byref", true)
5908 .Default(false))
5909 Tokens[I].int_data[0] = CXToken_Keyword;
5910 continue;
5911 }
5912
5913 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5914 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5915 Tokens[I].int_data[0] = CXToken_Keyword;
5916 continue;
5917 }
5918 }
5919 }
5920}
5921
5922extern "C" {
5923
5924void clang_annotateTokens(CXTranslationUnit TU,
5925 CXToken *Tokens, unsigned NumTokens,
5926 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005927 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005928 LOG_BAD_TU(TU);
5929 return;
5930 }
5931 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005932 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005934 }
5935
5936 LOG_FUNC_SECTION {
5937 *Log << TU << ' ';
5938 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5939 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5940 *Log << clang_getRange(bloc, eloc);
5941 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005942
5943 // Any token we don't specifically annotate will have a NULL cursor.
5944 CXCursor C = clang_getNullCursor();
5945 for (unsigned I = 0; I != NumTokens; ++I)
5946 Cursors[I] = C;
5947
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005948 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 if (!CXXUnit)
5950 return;
5951
5952 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5953
5954 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5955 llvm::CrashRecoveryContext CRC;
5956 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5957 GetSafetyThreadStackSize() * 2)) {
5958 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5959 }
5960}
5961
5962} // end: extern "C"
5963
5964//===----------------------------------------------------------------------===//
5965// Operations for querying linkage of a cursor.
5966//===----------------------------------------------------------------------===//
5967
5968extern "C" {
5969CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5970 if (!clang_isDeclaration(cursor.kind))
5971 return CXLinkage_Invalid;
5972
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005973 const Decl *D = cxcursor::getCursorDecl(cursor);
5974 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005975 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005976 case NoLinkage:
5977 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 case InternalLinkage: return CXLinkage_Internal;
5979 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5980 case ExternalLinkage: return CXLinkage_External;
5981 };
5982
5983 return CXLinkage_Invalid;
5984}
5985} // end: extern "C"
5986
5987//===----------------------------------------------------------------------===//
5988// Operations for querying language of a cursor.
5989//===----------------------------------------------------------------------===//
5990
5991static CXLanguageKind getDeclLanguage(const Decl *D) {
5992 if (!D)
5993 return CXLanguage_C;
5994
5995 switch (D->getKind()) {
5996 default:
5997 break;
5998 case Decl::ImplicitParam:
5999 case Decl::ObjCAtDefsField:
6000 case Decl::ObjCCategory:
6001 case Decl::ObjCCategoryImpl:
6002 case Decl::ObjCCompatibleAlias:
6003 case Decl::ObjCImplementation:
6004 case Decl::ObjCInterface:
6005 case Decl::ObjCIvar:
6006 case Decl::ObjCMethod:
6007 case Decl::ObjCProperty:
6008 case Decl::ObjCPropertyImpl:
6009 case Decl::ObjCProtocol:
6010 return CXLanguage_ObjC;
6011 case Decl::CXXConstructor:
6012 case Decl::CXXConversion:
6013 case Decl::CXXDestructor:
6014 case Decl::CXXMethod:
6015 case Decl::CXXRecord:
6016 case Decl::ClassTemplate:
6017 case Decl::ClassTemplatePartialSpecialization:
6018 case Decl::ClassTemplateSpecialization:
6019 case Decl::Friend:
6020 case Decl::FriendTemplate:
6021 case Decl::FunctionTemplate:
6022 case Decl::LinkageSpec:
6023 case Decl::Namespace:
6024 case Decl::NamespaceAlias:
6025 case Decl::NonTypeTemplateParm:
6026 case Decl::StaticAssert:
6027 case Decl::TemplateTemplateParm:
6028 case Decl::TemplateTypeParm:
6029 case Decl::UnresolvedUsingTypename:
6030 case Decl::UnresolvedUsingValue:
6031 case Decl::Using:
6032 case Decl::UsingDirective:
6033 case Decl::UsingShadow:
6034 return CXLanguage_CPlusPlus;
6035 }
6036
6037 return CXLanguage_C;
6038}
6039
6040extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041
6042static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6043 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6044 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006045
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006046 switch (D->getAvailability()) {
6047 case AR_Available:
6048 case AR_NotYetIntroduced:
6049 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006050 return getCursorAvailabilityForDecl(
6051 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006052 return CXAvailability_Available;
6053
6054 case AR_Deprecated:
6055 return CXAvailability_Deprecated;
6056
6057 case AR_Unavailable:
6058 return CXAvailability_NotAvailable;
6059 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006060
6061 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006062}
6063
Guy Benyei11169dd2012-12-18 14:30:41 +00006064enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6065 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6067 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006068
6069 return CXAvailability_Available;
6070}
6071
6072static CXVersion convertVersion(VersionTuple In) {
6073 CXVersion Out = { -1, -1, -1 };
6074 if (In.empty())
6075 return Out;
6076
6077 Out.Major = In.getMajor();
6078
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006079 Optional<unsigned> Minor = In.getMinor();
6080 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006081 Out.Minor = *Minor;
6082 else
6083 return Out;
6084
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006085 Optional<unsigned> Subminor = In.getSubminor();
6086 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 Out.Subminor = *Subminor;
6088
6089 return Out;
6090}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006091
6092static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6093 int *always_deprecated,
6094 CXString *deprecated_message,
6095 int *always_unavailable,
6096 CXString *unavailable_message,
6097 CXPlatformAvailability *availability,
6098 int availability_size) {
6099 bool HadAvailAttr = false;
6100 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006101 for (auto A : D->attrs()) {
6102 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006103 HadAvailAttr = true;
6104 if (always_deprecated)
6105 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006106 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006107 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006108 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006109 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110 continue;
6111 }
6112
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006113 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006114 HadAvailAttr = true;
6115 if (always_unavailable)
6116 *always_unavailable = 1;
6117 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006118 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006119 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6120 }
6121 continue;
6122 }
6123
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006124 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006125 HadAvailAttr = true;
6126 if (N < availability_size) {
6127 availability[N].Platform
6128 = cxstring::createDup(Avail->getPlatform()->getName());
6129 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6130 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6131 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6132 availability[N].Unavailable = Avail->getUnavailable();
6133 availability[N].Message = cxstring::createDup(Avail->getMessage());
6134 }
6135 ++N;
6136 }
6137 }
6138
6139 if (!HadAvailAttr)
6140 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6141 return getCursorPlatformAvailabilityForDecl(
6142 cast<Decl>(EnumConst->getDeclContext()),
6143 always_deprecated,
6144 deprecated_message,
6145 always_unavailable,
6146 unavailable_message,
6147 availability,
6148 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006149
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006150 return N;
6151}
6152
Guy Benyei11169dd2012-12-18 14:30:41 +00006153int clang_getCursorPlatformAvailability(CXCursor cursor,
6154 int *always_deprecated,
6155 CXString *deprecated_message,
6156 int *always_unavailable,
6157 CXString *unavailable_message,
6158 CXPlatformAvailability *availability,
6159 int availability_size) {
6160 if (always_deprecated)
6161 *always_deprecated = 0;
6162 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006163 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 if (always_unavailable)
6165 *always_unavailable = 0;
6166 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006167 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006168
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 if (!clang_isDeclaration(cursor.kind))
6170 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (!D)
6174 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006175
6176 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6177 deprecated_message,
6178 always_unavailable,
6179 unavailable_message,
6180 availability,
6181 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006182}
6183
6184void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6185 clang_disposeString(availability->Platform);
6186 clang_disposeString(availability->Message);
6187}
6188
6189CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6190 if (clang_isDeclaration(cursor.kind))
6191 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6192
6193 return CXLanguage_Invalid;
6194}
6195
6196 /// \brief If the given cursor is the "templated" declaration
6197 /// descibing a class or function template, return the class or
6198 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006199static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006201 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006203 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006204 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6205 return FunTmpl;
6206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006207 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6209 return ClassTmpl;
6210
6211 return D;
6212}
6213
6214CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6215 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const Decl *D = getCursorDecl(cursor)) {
6217 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 if (!DC)
6219 return clang_getNullCursor();
6220
6221 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6222 getCursorTU(cursor));
6223 }
6224 }
6225
6226 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006227 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 return MakeCXCursor(D, getCursorTU(cursor));
6229 }
6230
6231 return clang_getNullCursor();
6232}
6233
6234CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6235 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006236 if (const Decl *D = getCursorDecl(cursor)) {
6237 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 if (!DC)
6239 return clang_getNullCursor();
6240
6241 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6242 getCursorTU(cursor));
6243 }
6244 }
6245
6246 // FIXME: Note that we can't easily compute the lexical context of a
6247 // statement or expression, so we return nothing.
6248 return clang_getNullCursor();
6249}
6250
6251CXFile clang_getIncludedFile(CXCursor cursor) {
6252 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006253 return nullptr;
6254
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006255 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006256 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006257}
6258
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006259unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6260 if (C.kind != CXCursor_ObjCPropertyDecl)
6261 return CXObjCPropertyAttr_noattr;
6262
6263 unsigned Result = CXObjCPropertyAttr_noattr;
6264 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6265 ObjCPropertyDecl::PropertyAttributeKind Attr =
6266 PD->getPropertyAttributesAsWritten();
6267
6268#define SET_CXOBJCPROP_ATTR(A) \
6269 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6270 Result |= CXObjCPropertyAttr_##A
6271 SET_CXOBJCPROP_ATTR(readonly);
6272 SET_CXOBJCPROP_ATTR(getter);
6273 SET_CXOBJCPROP_ATTR(assign);
6274 SET_CXOBJCPROP_ATTR(readwrite);
6275 SET_CXOBJCPROP_ATTR(retain);
6276 SET_CXOBJCPROP_ATTR(copy);
6277 SET_CXOBJCPROP_ATTR(nonatomic);
6278 SET_CXOBJCPROP_ATTR(setter);
6279 SET_CXOBJCPROP_ATTR(atomic);
6280 SET_CXOBJCPROP_ATTR(weak);
6281 SET_CXOBJCPROP_ATTR(strong);
6282 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6283#undef SET_CXOBJCPROP_ATTR
6284
6285 return Result;
6286}
6287
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006288unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6289 if (!clang_isDeclaration(C.kind))
6290 return CXObjCDeclQualifier_None;
6291
6292 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6293 const Decl *D = getCursorDecl(C);
6294 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6295 QT = MD->getObjCDeclQualifier();
6296 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6297 QT = PD->getObjCDeclQualifier();
6298 if (QT == Decl::OBJC_TQ_None)
6299 return CXObjCDeclQualifier_None;
6300
6301 unsigned Result = CXObjCDeclQualifier_None;
6302 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6303 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6304 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6305 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6306 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6307 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6308
6309 return Result;
6310}
6311
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006312unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6313 if (!clang_isDeclaration(C.kind))
6314 return 0;
6315
6316 const Decl *D = getCursorDecl(C);
6317 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6318 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6319 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6320 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6321
6322 return 0;
6323}
6324
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006325unsigned clang_Cursor_isVariadic(CXCursor C) {
6326 if (!clang_isDeclaration(C.kind))
6327 return 0;
6328
6329 const Decl *D = getCursorDecl(C);
6330 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6331 return FD->isVariadic();
6332 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6333 return MD->isVariadic();
6334
6335 return 0;
6336}
6337
Guy Benyei11169dd2012-12-18 14:30:41 +00006338CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6339 if (!clang_isDeclaration(C.kind))
6340 return clang_getNullRange();
6341
6342 const Decl *D = getCursorDecl(C);
6343 ASTContext &Context = getCursorContext(C);
6344 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6345 if (!RC)
6346 return clang_getNullRange();
6347
6348 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6349}
6350
6351CXString clang_Cursor_getRawCommentText(CXCursor C) {
6352 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006353 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006354
6355 const Decl *D = getCursorDecl(C);
6356 ASTContext &Context = getCursorContext(C);
6357 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6358 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6359 StringRef();
6360
6361 // Don't duplicate the string because RawText points directly into source
6362 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006363 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
6366CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6367 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006368 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006369
6370 const Decl *D = getCursorDecl(C);
6371 const ASTContext &Context = getCursorContext(C);
6372 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6373
6374 if (RC) {
6375 StringRef BriefText = RC->getBriefText(Context);
6376
6377 // Don't duplicate the string because RawComment ensures that this memory
6378 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006379 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 }
6381
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006382 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006383}
6384
Guy Benyei11169dd2012-12-18 14:30:41 +00006385CXModule clang_Cursor_getModule(CXCursor C) {
6386 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006387 if (const ImportDecl *ImportD =
6388 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006389 return ImportD->getImportedModule();
6390 }
6391
Craig Topper69186e72014-06-08 08:38:04 +00006392 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006393}
6394
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006395CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6396 if (isNotUsableTU(TU)) {
6397 LOG_BAD_TU(TU);
6398 return nullptr;
6399 }
6400 if (!File)
6401 return nullptr;
6402 FileEntry *FE = static_cast<FileEntry *>(File);
6403
6404 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6405 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6406 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6407
6408 if (Module *Mod = Header.getModule()) {
6409 if (Header.getRole() != ModuleMap::ExcludedHeader)
6410 return Mod;
6411 }
6412 return nullptr;
6413}
6414
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006415CXFile clang_Module_getASTFile(CXModule CXMod) {
6416 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006417 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006418 Module *Mod = static_cast<Module*>(CXMod);
6419 return const_cast<FileEntry *>(Mod->getASTFile());
6420}
6421
Guy Benyei11169dd2012-12-18 14:30:41 +00006422CXModule clang_Module_getParent(CXModule CXMod) {
6423 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006424 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 Module *Mod = static_cast<Module*>(CXMod);
6426 return Mod->Parent;
6427}
6428
6429CXString clang_Module_getName(CXModule CXMod) {
6430 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006431 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006432 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006433 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434}
6435
6436CXString clang_Module_getFullName(CXModule CXMod) {
6437 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006438 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006440 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006441}
6442
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006443int clang_Module_isSystem(CXModule CXMod) {
6444 if (!CXMod)
6445 return 0;
6446 Module *Mod = static_cast<Module*>(CXMod);
6447 return Mod->IsSystem;
6448}
6449
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006450unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6451 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006452 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006453 LOG_BAD_TU(TU);
6454 return 0;
6455 }
6456 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006457 return 0;
6458 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006459 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6460 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6461 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006462}
6463
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006464CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6465 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006467 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006468 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006469 }
6470 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006471 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006473 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006474
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006475 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6476 if (Index < TopHeaders.size())
6477 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006478
Craig Topper69186e72014-06-08 08:38:04 +00006479 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006480}
6481
6482} // end: extern "C"
6483
6484//===----------------------------------------------------------------------===//
6485// C++ AST instrospection.
6486//===----------------------------------------------------------------------===//
6487
6488extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006489unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6490 if (!clang_isDeclaration(C.kind))
6491 return 0;
6492
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006493 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006494 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006495 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006496 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6497}
6498
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006499unsigned clang_CXXMethod_isConst(CXCursor C) {
6500 if (!clang_isDeclaration(C.kind))
6501 return 0;
6502
6503 const Decl *D = cxcursor::getCursorDecl(C);
6504 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006505 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006506 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6507}
6508
Guy Benyei11169dd2012-12-18 14:30:41 +00006509unsigned clang_CXXMethod_isStatic(CXCursor C) {
6510 if (!clang_isDeclaration(C.kind))
6511 return 0;
6512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006513 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006514 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006515 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006516 return (Method && Method->isStatic()) ? 1 : 0;
6517}
6518
6519unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6520 if (!clang_isDeclaration(C.kind))
6521 return 0;
6522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006523 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006524 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006525 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 return (Method && Method->isVirtual()) ? 1 : 0;
6527}
6528} // end: extern "C"
6529
6530//===----------------------------------------------------------------------===//
6531// Attribute introspection.
6532//===----------------------------------------------------------------------===//
6533
6534extern "C" {
6535CXType clang_getIBOutletCollectionType(CXCursor C) {
6536 if (C.kind != CXCursor_IBOutletCollectionAttr)
6537 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6538
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006539 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6541
6542 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6543}
6544} // end: extern "C"
6545
6546//===----------------------------------------------------------------------===//
6547// Inspecting memory usage.
6548//===----------------------------------------------------------------------===//
6549
6550typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6551
6552static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6553 enum CXTUResourceUsageKind k,
6554 unsigned long amount) {
6555 CXTUResourceUsageEntry entry = { k, amount };
6556 entries.push_back(entry);
6557}
6558
6559extern "C" {
6560
6561const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6562 const char *str = "";
6563 switch (kind) {
6564 case CXTUResourceUsage_AST:
6565 str = "ASTContext: expressions, declarations, and types";
6566 break;
6567 case CXTUResourceUsage_Identifiers:
6568 str = "ASTContext: identifiers";
6569 break;
6570 case CXTUResourceUsage_Selectors:
6571 str = "ASTContext: selectors";
6572 break;
6573 case CXTUResourceUsage_GlobalCompletionResults:
6574 str = "Code completion: cached global results";
6575 break;
6576 case CXTUResourceUsage_SourceManagerContentCache:
6577 str = "SourceManager: content cache allocator";
6578 break;
6579 case CXTUResourceUsage_AST_SideTables:
6580 str = "ASTContext: side tables";
6581 break;
6582 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6583 str = "SourceManager: malloc'ed memory buffers";
6584 break;
6585 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6586 str = "SourceManager: mmap'ed memory buffers";
6587 break;
6588 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6589 str = "ExternalASTSource: malloc'ed memory buffers";
6590 break;
6591 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6592 str = "ExternalASTSource: mmap'ed memory buffers";
6593 break;
6594 case CXTUResourceUsage_Preprocessor:
6595 str = "Preprocessor: malloc'ed memory";
6596 break;
6597 case CXTUResourceUsage_PreprocessingRecord:
6598 str = "Preprocessor: PreprocessingRecord";
6599 break;
6600 case CXTUResourceUsage_SourceManager_DataStructures:
6601 str = "SourceManager: data structures and tables";
6602 break;
6603 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6604 str = "Preprocessor: header search tables";
6605 break;
6606 }
6607 return str;
6608}
6609
6610CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006611 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006612 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006613 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 return usage;
6615 }
6616
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006617 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006618 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 ASTContext &astContext = astUnit->getASTContext();
6620
6621 // How much memory is used by AST nodes and types?
6622 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6623 (unsigned long) astContext.getASTAllocatedMemory());
6624
6625 // How much memory is used by identifiers?
6626 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6627 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6628
6629 // How much memory is used for selectors?
6630 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6631 (unsigned long) astContext.Selectors.getTotalMemory());
6632
6633 // How much memory is used by ASTContext's side tables?
6634 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6635 (unsigned long) astContext.getSideTableAllocatedMemory());
6636
6637 // How much memory is used for caching global code completion results?
6638 unsigned long completionBytes = 0;
6639 if (GlobalCodeCompletionAllocator *completionAllocator =
6640 astUnit->getCachedCompletionAllocator().getPtr()) {
6641 completionBytes = completionAllocator->getTotalMemory();
6642 }
6643 createCXTUResourceUsageEntry(*entries,
6644 CXTUResourceUsage_GlobalCompletionResults,
6645 completionBytes);
6646
6647 // How much memory is being used by SourceManager's content cache?
6648 createCXTUResourceUsageEntry(*entries,
6649 CXTUResourceUsage_SourceManagerContentCache,
6650 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6651
6652 // How much memory is being used by the MemoryBuffer's in SourceManager?
6653 const SourceManager::MemoryBufferSizes &srcBufs =
6654 astUnit->getSourceManager().getMemoryBufferSizes();
6655
6656 createCXTUResourceUsageEntry(*entries,
6657 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6658 (unsigned long) srcBufs.malloc_bytes);
6659 createCXTUResourceUsageEntry(*entries,
6660 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6661 (unsigned long) srcBufs.mmap_bytes);
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_SourceManager_DataStructures,
6664 (unsigned long) astContext.getSourceManager()
6665 .getDataStructureSizes());
6666
6667 // How much memory is being used by the ExternalASTSource?
6668 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6669 const ExternalASTSource::MemoryBufferSizes &sizes =
6670 esrc->getMemoryBufferSizes();
6671
6672 createCXTUResourceUsageEntry(*entries,
6673 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6674 (unsigned long) sizes.malloc_bytes);
6675 createCXTUResourceUsageEntry(*entries,
6676 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6677 (unsigned long) sizes.mmap_bytes);
6678 }
6679
6680 // How much memory is being used by the Preprocessor?
6681 Preprocessor &pp = astUnit->getPreprocessor();
6682 createCXTUResourceUsageEntry(*entries,
6683 CXTUResourceUsage_Preprocessor,
6684 pp.getTotalMemory());
6685
6686 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6687 createCXTUResourceUsageEntry(*entries,
6688 CXTUResourceUsage_PreprocessingRecord,
6689 pRec->getTotalMemory());
6690 }
6691
6692 createCXTUResourceUsageEntry(*entries,
6693 CXTUResourceUsage_Preprocessor_HeaderSearch,
6694 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006695
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 CXTUResourceUsage usage = { (void*) entries.get(),
6697 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006698 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006699 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006700 return usage;
6701}
6702
6703void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6704 if (usage.data)
6705 delete (MemUsageEntries*) usage.data;
6706}
6707
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006708CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6709 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006710 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006711 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006712
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006713 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006714 LOG_BAD_TU(TU);
6715 return skipped;
6716 }
6717
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006718 if (!file)
6719 return skipped;
6720
6721 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6722 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6723 if (!ppRec)
6724 return skipped;
6725
6726 ASTContext &Ctx = astUnit->getASTContext();
6727 SourceManager &sm = Ctx.getSourceManager();
6728 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6729 FileID wantedFileID = sm.translateFile(fileEntry);
6730
6731 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6732 std::vector<SourceRange> wantedRanges;
6733 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6734 i != ei; ++i) {
6735 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6736 wantedRanges.push_back(*i);
6737 }
6738
6739 skipped->count = wantedRanges.size();
6740 skipped->ranges = new CXSourceRange[skipped->count];
6741 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6742 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6743
6744 return skipped;
6745}
6746
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006747void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6748 if (ranges) {
6749 delete[] ranges->ranges;
6750 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006751 }
6752}
6753
Guy Benyei11169dd2012-12-18 14:30:41 +00006754} // end extern "C"
6755
6756void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6757 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6758 for (unsigned I = 0; I != Usage.numEntries; ++I)
6759 fprintf(stderr, " %s: %lu\n",
6760 clang_getTUResourceUsageName(Usage.entries[I].kind),
6761 Usage.entries[I].amount);
6762
6763 clang_disposeCXTUResourceUsage(Usage);
6764}
6765
6766//===----------------------------------------------------------------------===//
6767// Misc. utility functions.
6768//===----------------------------------------------------------------------===//
6769
6770/// Default to using an 8 MB stack size on "safety" threads.
6771static unsigned SafetyStackThreadSize = 8 << 20;
6772
6773namespace clang {
6774
6775bool RunSafely(llvm::CrashRecoveryContext &CRC,
6776 void (*Fn)(void*), void *UserData,
6777 unsigned Size) {
6778 if (!Size)
6779 Size = GetSafetyThreadStackSize();
6780 if (Size)
6781 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6782 return CRC.RunSafely(Fn, UserData);
6783}
6784
6785unsigned GetSafetyThreadStackSize() {
6786 return SafetyStackThreadSize;
6787}
6788
6789void SetSafetyThreadStackSize(unsigned Value) {
6790 SafetyStackThreadSize = Value;
6791}
6792
6793}
6794
6795void clang::setThreadBackgroundPriority() {
6796 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6797 return;
6798
6799 // FIXME: Move to llvm/Support and make it cross-platform.
6800#ifdef __APPLE__
6801 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6802#endif
6803}
6804
6805void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6806 if (!Unit)
6807 return;
6808
6809 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6810 DEnd = Unit->stored_diag_end();
6811 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006812 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 CXString Msg = clang_formatDiagnostic(&Diag,
6814 clang_defaultDiagnosticDisplayOptions());
6815 fprintf(stderr, "%s\n", clang_getCString(Msg));
6816 clang_disposeString(Msg);
6817 }
6818#ifdef LLVM_ON_WIN32
6819 // On Windows, force a flush, since there may be multiple copies of
6820 // stderr and stdout in the file system, all with different buffers
6821 // but writing to the same device.
6822 fflush(stderr);
6823#endif
6824}
6825
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006826MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6827 SourceLocation MacroDefLoc,
6828 CXTranslationUnit TU){
6829 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006830 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006831 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006832 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006833
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006834 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006835 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006836 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006837 if (MD) {
6838 for (MacroDirective::DefInfo
6839 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6840 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6841 return Def.getMacroInfo();
6842 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006843 }
6844
Craig Topper69186e72014-06-08 08:38:04 +00006845 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846}
6847
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006848const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6849 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006850 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006852 const IdentifierInfo *II = MacroDef->getName();
6853 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006854 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855
6856 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6857}
6858
6859MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6860 const Token &Tok,
6861 CXTranslationUnit TU) {
6862 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006864 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866
6867 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006869 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6870 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006871 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006872
6873 // Check that the token is inside the definition and not its argument list.
6874 SourceManager &SM = Unit->getSourceManager();
6875 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006879
6880 Preprocessor &PP = Unit->getPreprocessor();
6881 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6882 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884
Alp Toker2d57cea2014-05-17 04:53:25 +00006885 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006886 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006887 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006888
6889 // Check that the identifier is not one of the macro arguments.
6890 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006893 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6894 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006895 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006896
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006897 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006898}
6899
6900MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6901 SourceLocation Loc,
6902 CXTranslationUnit TU) {
6903 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006905
6906 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006907 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006908 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006909 Preprocessor &PP = Unit->getPreprocessor();
6910 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6913 Token Tok;
6914 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006916
6917 return checkForMacroInMacroDefinition(MI, Tok, TU);
6918}
6919
Guy Benyei11169dd2012-12-18 14:30:41 +00006920extern "C" {
6921
6922CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006923 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006924}
6925
6926} // end: extern "C"
6927
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006928Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6929 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006930 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006931 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006932 if (Unit->isMainFileAST())
6933 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006934 return *this;
6935 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006936 } else {
6937 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006938 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006939 return *this;
6940}
6941
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006942Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6943 *this << FE->getName();
6944 return *this;
6945}
6946
6947Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6948 CXString cursorName = clang_getCursorDisplayName(cursor);
6949 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6950 clang_disposeString(cursorName);
6951 return *this;
6952}
6953
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006954Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6955 CXFile File;
6956 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006957 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006958 CXString FileName = clang_getFileName(File);
6959 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6960 clang_disposeString(FileName);
6961 return *this;
6962}
6963
6964Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6965 CXSourceLocation BLoc = clang_getRangeStart(range);
6966 CXSourceLocation ELoc = clang_getRangeEnd(range);
6967
6968 CXFile BFile;
6969 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006970 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006971
6972 CXFile EFile;
6973 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006974 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006975
6976 CXString BFileName = clang_getFileName(BFile);
6977 if (BFile == EFile) {
6978 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6979 BLine, BColumn, ELine, EColumn);
6980 } else {
6981 CXString EFileName = clang_getFileName(EFile);
6982 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6983 BLine, BColumn)
6984 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6985 ELine, EColumn);
6986 clang_disposeString(EFileName);
6987 }
6988 clang_disposeString(BFileName);
6989 return *this;
6990}
6991
6992Logger &cxindex::Logger::operator<<(CXString Str) {
6993 *this << clang_getCString(Str);
6994 return *this;
6995}
6996
6997Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6998 LogOS << Fmt;
6999 return *this;
7000}
7001
7002cxindex::Logger::~Logger() {
7003 LogOS.flush();
7004
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00007005 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007006
7007 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7008
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007009 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007010 OS << "[libclang:" << Name << ':';
7011
7012 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00007013#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007014 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7015 OS << tid << ':';
7016#endif
7017
7018 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7019 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7020 OS << Msg.str() << '\n';
7021
7022 if (Trace) {
7023 llvm::sys::PrintStackTrace(stderr);
7024 OS << "--------------------------------------------------\n";
7025 }
7026}