blob: bb9ba0b0d4ede190a4ac0b97562eeb8fd1eed45e [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1857 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001858 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001859 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001860 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001861 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001862 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001863 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864
Guy Benyei11169dd2012-12-18 14:30:41 +00001865private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1868 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1870 void AddStmt(const Stmt *S);
1871 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001874 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001875};
1876} // end anonyous namespace
1877
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 // 'S' should always be non-null, since it comes from the
1880 // statement we are visiting.
1881 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1882}
1883
1884void
1885EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1886 if (Qualifier)
1887 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1888}
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 if (S)
1892 WL.push_back(StmtVisit(S, Parent));
1893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(DeclVisit(D, Parent, isFirst));
1897}
1898void EnqueueVisitor::
1899 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1900 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001902}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 if (D)
1905 WL.push_back(MemberRefVisit(D, L, Parent));
1906}
1907void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1908 if (TI)
1909 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1910 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001912 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 AddStmt(*Child);
1915 }
1916 if (size == WL.size())
1917 return;
1918 // Now reverse the entries we just added. This will match the DFS
1919 // ordering performed by the worklist.
1920 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1921 std::reverse(I, E);
1922}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923namespace {
1924class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1925 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001926 /// \brief Process clauses with list of variables.
1927 template <typename T>
1928 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929public:
1930 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1931#define OPENMP_CLAUSE(Name, Class) \
1932 void Visit##Class(const Class *C);
1933#include "clang/Basic/OpenMPKinds.def"
1934};
1935
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001936void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1937 Visitor->AddStmt(C->getCondition());
1938}
1939
Alexey Bataev568a8332014-03-06 06:15:19 +00001940void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1941 Visitor->AddStmt(C->getNumThreads());
1942}
1943
Alexey Bataev62c87d22014-03-21 04:51:18 +00001944void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1945 Visitor->AddStmt(C->getSafelen());
1946}
1947
Alexander Musman8bd31e62014-05-27 15:12:19 +00001948void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1949 Visitor->AddStmt(C->getNumForLoops());
1950}
1951
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001953
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001954void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1955
Alexey Bataev56dafe82014-06-20 07:16:17 +00001956void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1957 Visitor->AddStmt(C->getChunkSize());
1958}
1959
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001960void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1961
Alexey Bataev236070f2014-06-20 11:19:47 +00001962void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1963
Alexey Bataev756c1962013-09-24 03:17:45 +00001964template<typename T>
1965void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001966 for (const auto *I : Node->varlists())
1967 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001968}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001969
1970void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001971 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001972}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001973void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1974 const OMPFirstprivateClause *C) {
1975 VisitOMPClauseList(C);
1976}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001977void OMPClauseEnqueue::VisitOMPLastprivateClause(
1978 const OMPLastprivateClause *C) {
1979 VisitOMPClauseList(C);
1980}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001981void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001982 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001983}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001984void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1985 VisitOMPClauseList(C);
1986}
Alexander Musman8dba6642014-04-22 13:09:42 +00001987void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1988 VisitOMPClauseList(C);
1989 Visitor->AddStmt(C->getStep());
1990}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001991void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1992 VisitOMPClauseList(C);
1993 Visitor->AddStmt(C->getAlignment());
1994}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001995void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1996 VisitOMPClauseList(C);
1997}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001998void
1999OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2000 VisitOMPClauseList(C);
2001}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002002}
Alexey Bataev756c1962013-09-24 03:17:45 +00002003
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2005 unsigned size = WL.size();
2006 OMPClauseEnqueue Visitor(this);
2007 Visitor.Visit(S);
2008 if (size == WL.size())
2009 return;
2010 // Now reverse the entries we just added. This will match the DFS
2011 // ordering performed by the worklist.
2012 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2013 std::reverse(I, E);
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2017}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002018void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002019 AddDecl(B->getBlockDecl());
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 EnqueueChildren(E);
2023 AddTypeLoc(E->getTypeSourceInfo());
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2026 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 E = S->body_rend(); I != E; ++I) {
2028 AddStmt(*I);
2029 }
2030}
2031void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 AddStmt(S->getSubStmt());
2034 AddDeclarationNameInfo(S);
2035 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2036 AddNestedNameSpecifierLoc(QualifierLoc);
2037}
2038
2039void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2042 AddDeclarationNameInfo(E);
2043 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2044 AddNestedNameSpecifierLoc(QualifierLoc);
2045 if (!E->isImplicitAccess())
2046 AddStmt(E->getBase());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 // Enqueue the initializer , if any.
2050 AddStmt(E->getInitializer());
2051 // Enqueue the array size, if any.
2052 AddStmt(E->getArraySize());
2053 // Enqueue the allocated type.
2054 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2055 // Enqueue the placement arguments.
2056 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2057 AddStmt(E->getPlacementArg(I-1));
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2061 AddStmt(CE->getArg(I-1));
2062 AddStmt(CE->getCallee());
2063 AddStmt(CE->getArg(0));
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2066 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 // Visit the name of the type being destroyed.
2068 AddTypeLoc(E->getDestroyedTypeInfo());
2069 // Visit the scope type that looks disturbingly like the nested-name-specifier
2070 // but isn't.
2071 AddTypeLoc(E->getScopeTypeInfo());
2072 // Visit the nested-name-specifier.
2073 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2074 AddNestedNameSpecifierLoc(QualifierLoc);
2075 // Visit base expression.
2076 AddStmt(E->getBase());
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2079 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddTypeLoc(E->getTypeSourceInfo());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2083 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 EnqueueChildren(E);
2085 AddTypeLoc(E->getTypeSourceInfo());
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 EnqueueChildren(E);
2089 if (E->isTypeOperand())
2090 AddTypeLoc(E->getTypeOperandSourceInfo());
2091}
2092
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2094 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 EnqueueChildren(E);
2096 AddTypeLoc(E->getTypeSourceInfo());
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 EnqueueChildren(E);
2100 if (E->isTypeOperand())
2101 AddTypeLoc(E->getTypeOperandSourceInfo());
2102}
2103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 EnqueueChildren(S);
2106 AddDecl(S->getExceptionDecl());
2107}
2108
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 if (DR->hasExplicitTemplateArgs()) {
2111 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2112 }
2113 WL.push_back(DeclRefExprParts(DR, Parent));
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2116 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2118 AddDeclarationNameInfo(E);
2119 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 unsigned size = WL.size();
2123 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002124 for (const auto *D : S->decls()) {
2125 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 isFirst = false;
2127 }
2128 if (size == WL.size())
2129 return;
2130 // Now reverse the entries we just added. This will match the DFS
2131 // ordering performed by the worklist.
2132 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2133 std::reverse(I, E);
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 D = E->designators_rbegin(), DEnd = E->designators_rend();
2139 D != DEnd; ++D) {
2140 if (D->isFieldDesignator()) {
2141 if (FieldDecl *Field = D->getField())
2142 AddMemberRef(Field, D->getFieldLoc());
2143 continue;
2144 }
2145 if (D->isArrayDesignator()) {
2146 AddStmt(E->getArrayIndex(*D));
2147 continue;
2148 }
2149 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2150 AddStmt(E->getArrayRangeEnd(*D));
2151 AddStmt(E->getArrayRangeStart(*D));
2152 }
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(E);
2156 AddTypeLoc(E->getTypeInfoAsWritten());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 AddStmt(FS->getBody());
2160 AddStmt(FS->getInc());
2161 AddStmt(FS->getCond());
2162 AddDecl(FS->getConditionVariable());
2163 AddStmt(FS->getInit());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 AddStmt(If->getElse());
2170 AddStmt(If->getThen());
2171 AddStmt(If->getCond());
2172 AddDecl(If->getConditionVariable());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 // We care about the syntactic form of the initializer list, only.
2176 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2177 IE = Syntactic;
2178 EnqueueChildren(IE);
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 WL.push_back(MemberExprParts(M, Parent));
2182
2183 // If the base of the member access expression is an implicit 'this', don't
2184 // visit it.
2185 // FIXME: If we ever want to show these implicit accesses, this will be
2186 // unfortunate. However, clang_getCursor() relies on this behavior.
2187 if (!M->isImplicitAccess())
2188 AddStmt(M->getBase());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddTypeLoc(E->getEncodedTypeSourceInfo());
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(M);
2195 AddTypeLoc(M->getClassReceiverTypeInfo());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 // Visit the components of the offsetof expression.
2199 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2200 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2201 const OffsetOfNode &Node = E->getComponent(I-1);
2202 switch (Node.getKind()) {
2203 case OffsetOfNode::Array:
2204 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2205 break;
2206 case OffsetOfNode::Field:
2207 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2208 break;
2209 case OffsetOfNode::Identifier:
2210 case OffsetOfNode::Base:
2211 continue;
2212 }
2213 }
2214 // Visit the type into which we're computing the offset.
2215 AddTypeLoc(E->getTypeSourceInfo());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2219 WL.push_back(OverloadExprParts(E, Parent));
2220}
2221void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 EnqueueChildren(E);
2224 if (E->isArgumentType())
2225 AddTypeLoc(E->getArgumentTypeInfo());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 EnqueueChildren(S);
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddStmt(S->getBody());
2232 AddStmt(S->getCond());
2233 AddDecl(S->getConditionVariable());
2234}
2235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 AddStmt(W->getBody());
2238 AddStmt(W->getCond());
2239 AddDecl(W->getConditionVariable());
2240}
2241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 for (unsigned I = E->getNumArgs(); I > 0; --I)
2244 AddTypeLoc(E->getArg(I-1));
2245}
2246
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 AddTypeLoc(E->getQueriedTypeSourceInfo());
2249}
2250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 EnqueueChildren(E);
2253}
2254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 VisitOverloadExpr(U);
2257 if (!U->isImplicitAccess())
2258 AddStmt(U->getBase());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddStmt(E->getSubExpr());
2262 AddTypeLoc(E->getWrittenTypeInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 WL.push_back(SizeOfPackExprParts(E, Parent));
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 // If the opaque value has a source expression, just transparently
2269 // visit that. This is useful for (e.g.) pseudo-object expressions.
2270 if (Expr *SourceExpr = E->getSourceExpr())
2271 return Visit(SourceExpr);
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(E->getBody());
2275 WL.push_back(LambdaExprParts(E, Parent));
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 // Treat the expression like its syntactic form.
2279 Visit(E->getSyntacticForm());
2280}
2281
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002282void EnqueueVisitor::VisitOMPExecutableDirective(
2283 const OMPExecutableDirective *D) {
2284 EnqueueChildren(D);
2285 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2286 E = D->clauses().end();
2287 I != E; ++I)
2288 EnqueueChildren(*I);
2289}
2290
2291void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2292 VisitOMPExecutableDirective(D);
2293}
2294
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002295void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2296 VisitOMPExecutableDirective(D);
2297}
2298
Alexey Bataevf29276e2014-06-18 04:14:57 +00002299void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2300 VisitOMPExecutableDirective(D);
2301}
2302
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002303void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2304 VisitOMPExecutableDirective(D);
2305}
2306
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002307void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2308 VisitOMPExecutableDirective(D);
2309}
2310
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002311void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2312 VisitOMPExecutableDirective(D);
2313}
2314
Alexey Bataev4acb8592014-07-07 13:01:15 +00002315void
2316EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2322}
2323
2324bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2325 if (RegionOfInterest.isValid()) {
2326 SourceRange Range = getRawCursorExtent(C);
2327 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2328 return false;
2329 }
2330 return true;
2331}
2332
2333bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2334 while (!WL.empty()) {
2335 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002336 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002337
2338 // Set the Parent field, then back to its old value once we're done.
2339 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2340
2341 switch (LI.getKind()) {
2342 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 if (!D)
2345 continue;
2346
2347 // For now, perform default visitation for Decls.
2348 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2349 cast<DeclVisit>(&LI)->isFirst())))
2350 return true;
2351
2352 continue;
2353 }
2354 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2355 const ASTTemplateArgumentListInfo *ArgList =
2356 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2357 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2358 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2359 Arg != ArgEnd; ++Arg) {
2360 if (VisitTemplateArgumentLoc(*Arg))
2361 return true;
2362 }
2363 continue;
2364 }
2365 case VisitorJob::TypeLocVisitKind: {
2366 // Perform default visitation for TypeLocs.
2367 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2368 return true;
2369 continue;
2370 }
2371 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 if (LabelStmt *stmt = LS->getStmt()) {
2374 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2375 TU))) {
2376 return true;
2377 }
2378 }
2379 continue;
2380 }
2381
2382 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2383 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2384 if (VisitNestedNameSpecifierLoc(V->get()))
2385 return true;
2386 continue;
2387 }
2388
2389 case VisitorJob::DeclarationNameInfoVisitKind: {
2390 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2391 ->get()))
2392 return true;
2393 continue;
2394 }
2395 case VisitorJob::MemberRefVisitKind: {
2396 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2397 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2398 return true;
2399 continue;
2400 }
2401 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 if (!S)
2404 continue;
2405
2406 // Update the current cursor.
2407 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2408 if (!IsInRegionOfInterest(Cursor))
2409 continue;
2410 switch (Visitor(Cursor, Parent, ClientData)) {
2411 case CXChildVisit_Break: return true;
2412 case CXChildVisit_Continue: break;
2413 case CXChildVisit_Recurse:
2414 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002415 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 EnqueueWorkList(WL, S);
2417 break;
2418 }
2419 continue;
2420 }
2421 case VisitorJob::MemberExprPartsKind: {
2422 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002424
2425 // Visit the nested-name-specifier
2426 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2427 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2428 return true;
2429
2430 // Visit the declaration name.
2431 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2432 return true;
2433
2434 // Visit the explicitly-specified template arguments, if any.
2435 if (M->hasExplicitTemplateArgs()) {
2436 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2437 *ArgEnd = Arg + M->getNumTemplateArgs();
2438 Arg != ArgEnd; ++Arg) {
2439 if (VisitTemplateArgumentLoc(*Arg))
2440 return true;
2441 }
2442 }
2443 continue;
2444 }
2445 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 // Visit nested-name-specifier, if present.
2448 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2449 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2450 return true;
2451 // Visit declaration name.
2452 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2453 return true;
2454 continue;
2455 }
2456 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002457 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 // Visit the nested-name-specifier.
2459 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2460 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2461 return true;
2462 // Visit the declaration name.
2463 if (VisitDeclarationNameInfo(O->getNameInfo()))
2464 return true;
2465 // Visit the overloaded declaration reference.
2466 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2467 return true;
2468 continue;
2469 }
2470 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 NamedDecl *Pack = E->getPack();
2473 if (isa<TemplateTypeParmDecl>(Pack)) {
2474 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2475 E->getPackLoc(), TU)))
2476 return true;
2477
2478 continue;
2479 }
2480
2481 if (isa<TemplateTemplateParmDecl>(Pack)) {
2482 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2483 E->getPackLoc(), TU)))
2484 return true;
2485
2486 continue;
2487 }
2488
2489 // Non-type template parameter packs and function parameter packs are
2490 // treated like DeclRefExpr cursors.
2491 continue;
2492 }
2493
2494 case VisitorJob::LambdaExprPartsKind: {
2495 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2498 CEnd = E->explicit_capture_end();
2499 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002500 // FIXME: Lambda init-captures.
2501 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002503
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2505 C->getLocation(),
2506 TU)))
2507 return true;
2508 }
2509
2510 // Visit parameters and return type, if present.
2511 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2512 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2513 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2514 // Visit the whole type.
2515 if (Visit(TL))
2516 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002517 } else if (FunctionProtoTypeLoc Proto =
2518 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 if (E->hasExplicitParameters()) {
2520 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002521 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2522 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 return true;
2524 } else {
2525 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002526 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002527 return true;
2528 }
2529 }
2530 }
2531 break;
2532 }
2533
2534 case VisitorJob::PostChildrenVisitKind:
2535 if (PostChildrenVisitor(Parent, ClientData))
2536 return true;
2537 break;
2538 }
2539 }
2540 return false;
2541}
2542
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002543bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002544 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 if (!WorkListFreeList.empty()) {
2546 WL = WorkListFreeList.back();
2547 WL->clear();
2548 WorkListFreeList.pop_back();
2549 }
2550 else {
2551 WL = new VisitorWorkList();
2552 WorkListCache.push_back(WL);
2553 }
2554 EnqueueWorkList(*WL, S);
2555 bool result = RunVisitorWorkList(*WL);
2556 WorkListFreeList.push_back(WL);
2557 return result;
2558}
2559
2560namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002561typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002562RefNamePieces
2563buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2564 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2565 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2567 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2568 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2569
2570 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2571
2572 RefNamePieces Pieces;
2573
2574 if (WantQualifier && QLoc.isValid())
2575 Pieces.push_back(QLoc);
2576
2577 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2578 Pieces.push_back(NI.getLoc());
2579
2580 if (WantTemplateArgs && TemplateArgs)
2581 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2582 TemplateArgs->RAngleLoc));
2583
2584 if (Kind == DeclarationName::CXXOperatorName) {
2585 Pieces.push_back(SourceLocation::getFromRawEncoding(
2586 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2587 Pieces.push_back(SourceLocation::getFromRawEncoding(
2588 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2589 }
2590
2591 if (WantSinglePiece) {
2592 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2593 Pieces.clear();
2594 Pieces.push_back(R);
2595 }
2596
2597 return Pieces;
2598}
2599}
2600
2601//===----------------------------------------------------------------------===//
2602// Misc. API hooks.
2603//===----------------------------------------------------------------------===//
2604
Chad Rosier05c71aa2013-03-27 18:28:23 +00002605static void fatal_error_handler(void *user_data, const std::string& reason,
2606 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 // Write the result out to stderr avoiding errs() because raw_ostreams can
2608 // call report_fatal_error.
2609 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2610 ::abort();
2611}
2612
Chandler Carruth66660742014-06-27 16:37:27 +00002613namespace {
2614struct RegisterFatalErrorHandler {
2615 RegisterFatalErrorHandler() {
2616 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2617 }
2618};
2619}
2620
2621static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2622
Guy Benyei11169dd2012-12-18 14:30:41 +00002623extern "C" {
2624CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2625 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002626 // We use crash recovery to make some of our APIs more reliable, implicitly
2627 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002628 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2629 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002630
Chandler Carruth66660742014-06-27 16:37:27 +00002631 // Look through the managed static to trigger construction of the managed
2632 // static which registers our fatal error handler. This ensures it is only
2633 // registered once.
2634 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002635
2636 CIndexer *CIdxr = new CIndexer();
2637 if (excludeDeclarationsFromPCH)
2638 CIdxr->setOnlyLocalDecls();
2639 if (displayDiagnostics)
2640 CIdxr->setDisplayDiagnostics();
2641
2642 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2643 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2644 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2645 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2646 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2647 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2648
2649 return CIdxr;
2650}
2651
2652void clang_disposeIndex(CXIndex CIdx) {
2653 if (CIdx)
2654 delete static_cast<CIndexer *>(CIdx);
2655}
2656
2657void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2658 if (CIdx)
2659 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2660}
2661
2662unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2663 if (CIdx)
2664 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2665 return 0;
2666}
2667
2668void clang_toggleCrashRecovery(unsigned isEnabled) {
2669 if (isEnabled)
2670 llvm::CrashRecoveryContext::Enable();
2671 else
2672 llvm::CrashRecoveryContext::Disable();
2673}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674
Guy Benyei11169dd2012-12-18 14:30:41 +00002675CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2676 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002677 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002678 enum CXErrorCode Result =
2679 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002680 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681 assert((TU && Result == CXError_Success) ||
2682 (!TU && Result != CXError_Success));
2683 return TU;
2684}
2685
2686enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2687 const char *ast_filename,
2688 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002689 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002690 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002691
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 if (!CIdx || !ast_filename || !out_TU)
2693 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002694
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002695 LOG_FUNC_SECTION {
2696 *Log << ast_filename;
2697 }
2698
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2700 FileSystemOptions FileSystemOpts;
2701
2702 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002704 CXXIdx->getOnlyLocalDecls(), None,
2705 /*CaptureDiagnostics=*/true,
2706 /*AllowPCHWithCompilerErrors=*/true,
2707 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002708 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2709 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002710}
2711
2712unsigned clang_defaultEditingTranslationUnitOptions() {
2713 return CXTranslationUnit_PrecompiledPreamble |
2714 CXTranslationUnit_CacheCompletionResults;
2715}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716
Guy Benyei11169dd2012-12-18 14:30:41 +00002717CXTranslationUnit
2718clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2719 const char *source_filename,
2720 int num_command_line_args,
2721 const char * const *command_line_args,
2722 unsigned num_unsaved_files,
2723 struct CXUnsavedFile *unsaved_files) {
2724 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2725 return clang_parseTranslationUnit(CIdx, source_filename,
2726 command_line_args, num_command_line_args,
2727 unsaved_files, num_unsaved_files,
2728 Options);
2729}
2730
2731struct ParseTranslationUnitInfo {
2732 CXIndex CIdx;
2733 const char *source_filename;
2734 const char *const *command_line_args;
2735 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002736 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002738 CXTranslationUnit *out_TU;
Alp Toker9d85b182014-07-07 01:23:14 +00002739 mutable CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002740};
2741static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002742 const ParseTranslationUnitInfo *PTUI =
2743 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 CXIndex CIdx = PTUI->CIdx;
2745 const char *source_filename = PTUI->source_filename;
2746 const char * const *command_line_args = PTUI->command_line_args;
2747 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002750
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002751 // Set up the initial return values.
2752 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002753 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002754 PTUI->result = CXError_Failure;
2755
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002756 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002757 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002760 }
2761
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2763
2764 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2765 setThreadBackgroundPriority();
2766
2767 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2768 // FIXME: Add a flag for modules.
2769 TranslationUnitKind TUKind
2770 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002771 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 = options & CXTranslationUnit_CacheCompletionResults;
2773 bool IncludeBriefCommentsInCodeCompletion
2774 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2775 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2776 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2777
2778 // Configure the diagnostics.
2779 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002780 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002781
2782 // Recover resources if we crash before exiting this function.
2783 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2784 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002785 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002786
Ahmed Charlesb8984322014-03-07 20:03:18 +00002787 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2788 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002789
2790 // Recover resources if we crash before exiting this function.
2791 llvm::CrashRecoveryContextCleanupRegistrar<
2792 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2793
Alp Toker9d85b182014-07-07 01:23:14 +00002794 for (auto &UF : PTUI->unsaved_files) {
2795 llvm::MemoryBuffer *MB =
2796 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2797 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 }
2799
Ahmed Charlesb8984322014-03-07 20:03:18 +00002800 std::unique_ptr<std::vector<const char *>> Args(
2801 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002802
2803 // Recover resources if we crash before exiting this method.
2804 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2805 ArgsCleanup(Args.get());
2806
2807 // Since the Clang C library is primarily used by batch tools dealing with
2808 // (often very broken) source code, where spell-checking can have a
2809 // significant negative impact on performance (particularly when
2810 // precompiled headers are involved), we disable it by default.
2811 // Only do this if we haven't found a spell-checking-related argument.
2812 bool FoundSpellCheckingArgument = false;
2813 for (int I = 0; I != num_command_line_args; ++I) {
2814 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2815 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2816 FoundSpellCheckingArgument = true;
2817 break;
2818 }
2819 }
2820 if (!FoundSpellCheckingArgument)
2821 Args->push_back("-fno-spell-checking");
2822
2823 Args->insert(Args->end(), command_line_args,
2824 command_line_args + num_command_line_args);
2825
2826 // The 'source_filename' argument is optional. If the caller does not
2827 // specify it then it is assumed that the source file is specified
2828 // in the actual argument list.
2829 // Put the source file after command_line_args otherwise if '-x' flag is
2830 // present it will be unused.
2831 if (source_filename)
2832 Args->push_back(source_filename);
2833
2834 // Do we need the detailed preprocessing record?
2835 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2836 Args->push_back("-Xclang");
2837 Args->push_back("-detailed-preprocessing-record");
2838 }
2839
2840 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002841 std::unique_ptr<ASTUnit> ErrUnit;
2842 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002843 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002844 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2845 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2846 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2847 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2848 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2849 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002850
2851 if (NumErrors != Diags->getClient()->getNumErrors()) {
2852 // Make sure to check that 'Unit' is non-NULL.
2853 if (CXXIdx->getDisplayDiagnostics())
2854 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2855 }
2856
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2858 PTUI->result = CXError_ASTReadError;
2859 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002860 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2862 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002863}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864
2865CXTranslationUnit
2866clang_parseTranslationUnit(CXIndex CIdx,
2867 const char *source_filename,
2868 const char *const *command_line_args,
2869 int num_command_line_args,
2870 struct CXUnsavedFile *unsaved_files,
2871 unsigned num_unsaved_files,
2872 unsigned options) {
2873 CXTranslationUnit TU;
2874 enum CXErrorCode Result = clang_parseTranslationUnit2(
2875 CIdx, source_filename, command_line_args, num_command_line_args,
2876 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002877 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002878 assert((TU && Result == CXError_Success) ||
2879 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002880 return TU;
2881}
2882
2883enum CXErrorCode clang_parseTranslationUnit2(
2884 CXIndex CIdx,
2885 const char *source_filename,
2886 const char *const *command_line_args,
2887 int num_command_line_args,
2888 struct CXUnsavedFile *unsaved_files,
2889 unsigned num_unsaved_files,
2890 unsigned options,
2891 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002892 LOG_FUNC_SECTION {
2893 *Log << source_filename << ": ";
2894 for (int i = 0; i != num_command_line_args; ++i)
2895 *Log << command_line_args[i] << " ";
2896 }
2897
Alp Toker9d85b182014-07-07 01:23:14 +00002898 if (num_unsaved_files && !unsaved_files)
2899 return CXError_InvalidArguments;
2900
2901 ParseTranslationUnitInfo PTUI = {
2902 CIdx,
2903 source_filename,
2904 command_line_args,
2905 num_command_line_args,
2906 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2907 options,
2908 out_TU,
2909 CXError_Failure};
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 llvm::CrashRecoveryContext CRC;
2911
2912 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2913 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2914 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2915 fprintf(stderr, " 'command_line_args' : [");
2916 for (int i = 0; i != num_command_line_args; ++i) {
2917 if (i)
2918 fprintf(stderr, ", ");
2919 fprintf(stderr, "'%s'", command_line_args[i]);
2920 }
2921 fprintf(stderr, "],\n");
2922 fprintf(stderr, " 'unsaved_files' : [");
2923 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2924 if (i)
2925 fprintf(stderr, ", ");
2926 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2927 unsaved_files[i].Length);
2928 }
2929 fprintf(stderr, "],\n");
2930 fprintf(stderr, " 'options' : %d,\n", options);
2931 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002932
2933 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935 if (CXTranslationUnit *TU = PTUI.out_TU)
2936 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 }
2938
2939 return PTUI.result;
2940}
2941
2942unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2943 return CXSaveTranslationUnit_None;
2944}
2945
2946namespace {
2947
2948struct SaveTranslationUnitInfo {
2949 CXTranslationUnit TU;
2950 const char *FileName;
2951 unsigned options;
2952 CXSaveError result;
2953};
2954
2955}
2956
2957static void clang_saveTranslationUnit_Impl(void *UserData) {
2958 SaveTranslationUnitInfo *STUI =
2959 static_cast<SaveTranslationUnitInfo*>(UserData);
2960
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002961 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2963 setThreadBackgroundPriority();
2964
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002965 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2967}
2968
2969int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2970 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << TU << ' ' << FileName;
2973 }
2974
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002975 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002976 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002978 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002979
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002980 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002981 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2982 if (!CXXUnit->hasSema())
2983 return CXSaveError_InvalidTU;
2984
2985 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2986
2987 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2988 getenv("LIBCLANG_NOTHREADS")) {
2989 clang_saveTranslationUnit_Impl(&STUI);
2990
2991 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2992 PrintLibclangResourceUsage(TU);
2993
2994 return STUI.result;
2995 }
2996
2997 // We have an AST that has invalid nodes due to compiler errors.
2998 // Use a crash recovery thread for protection.
2999
3000 llvm::CrashRecoveryContext CRC;
3001
3002 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3003 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3004 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3005 fprintf(stderr, " 'options' : %d,\n", options);
3006 fprintf(stderr, "}\n");
3007
3008 return CXSaveError_Unknown;
3009
3010 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3011 PrintLibclangResourceUsage(TU);
3012 }
3013
3014 return STUI.result;
3015}
3016
3017void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3018 if (CTUnit) {
3019 // If the translation unit has been marked as unsafe to free, just discard
3020 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3022 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 return;
3024
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003025 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003026 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3028 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003029 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 delete CTUnit;
3031 }
3032}
3033
3034unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3035 return CXReparse_None;
3036}
3037
3038struct ReparseTranslationUnitInfo {
3039 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003040 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 unsigned options;
Alp Toker9d85b182014-07-07 01:23:14 +00003042 mutable int result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003043};
3044
3045static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003046 const ReparseTranslationUnitInfo *RTUI =
3047 static_cast<ReparseTranslationUnitInfo *>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003049
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051 unsigned options = RTUI->options;
3052 (void) options;
3053
3054 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003055 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003056 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 RTUI->result = CXError_InvalidArguments;
3058 return;
3059 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003060
3061 // Reset the associated diagnostics.
3062 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003063 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003065 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3067 setThreadBackgroundPriority();
3068
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003069 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003071
3072 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3073 new std::vector<ASTUnit::RemappedFile>());
3074
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 // Recover resources if we crash before exiting this function.
3076 llvm::CrashRecoveryContextCleanupRegistrar<
3077 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003078
3079 for (auto &UF : RTUI->unsaved_files) {
3080 llvm::MemoryBuffer *MB =
3081 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3082 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003085 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003086 RTUI->result = CXError_Success;
3087 else if (isASTReadError(CXXUnit))
3088 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003089}
3090
3091int clang_reparseTranslationUnit(CXTranslationUnit TU,
3092 unsigned num_unsaved_files,
3093 struct CXUnsavedFile *unsaved_files,
3094 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003095 LOG_FUNC_SECTION {
3096 *Log << TU;
3097 }
3098
Alp Toker9d85b182014-07-07 01:23:14 +00003099 if (num_unsaved_files && !unsaved_files)
3100 return CXError_InvalidArguments;
3101
3102 ReparseTranslationUnitInfo RTUI = {
3103 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
3104 CXError_Failure};
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
3106 if (getenv("LIBCLANG_NOTHREADS")) {
3107 clang_reparseTranslationUnit_Impl(&RTUI);
3108 return RTUI.result;
3109 }
3110
3111 llvm::CrashRecoveryContext CRC;
3112
3113 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3114 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003115 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003116 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3118 PrintLibclangResourceUsage(TU);
3119
3120 return RTUI.result;
3121}
3122
3123
3124CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003125 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003127 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003130 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003131 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003132}
3133
3134CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003135 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003136 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003137 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003138 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3142}
3143
3144} // end: extern "C"
3145
3146//===----------------------------------------------------------------------===//
3147// CXFile Operations.
3148//===----------------------------------------------------------------------===//
3149
3150extern "C" {
3151CXString clang_getFileName(CXFile SFile) {
3152 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003153 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003154
3155 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003156 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003157}
3158
3159time_t clang_getFileTime(CXFile SFile) {
3160 if (!SFile)
3161 return 0;
3162
3163 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3164 return FEnt->getModificationTime();
3165}
3166
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003167CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003168 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003169 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003170 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003171 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003172
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003173 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003174
3175 FileManager &FMgr = CXXUnit->getFileManager();
3176 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3177}
3178
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003179unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3180 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003181 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003182 LOG_BAD_TU(TU);
3183 return 0;
3184 }
3185
3186 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 return 0;
3188
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003189 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 FileEntry *FEnt = static_cast<FileEntry *>(file);
3191 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3192 .isFileMultipleIncludeGuarded(FEnt);
3193}
3194
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003195int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3196 if (!file || !outID)
3197 return 1;
3198
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003199 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003200 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3201 outID->data[0] = ID.getDevice();
3202 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003203 outID->data[2] = FEnt->getModificationTime();
3204 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003205}
3206
Guy Benyei11169dd2012-12-18 14:30:41 +00003207} // end: extern "C"
3208
3209//===----------------------------------------------------------------------===//
3210// CXCursor Operations.
3211//===----------------------------------------------------------------------===//
3212
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003213static const Decl *getDeclFromExpr(const Stmt *E) {
3214 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return getDeclFromExpr(CE->getSubExpr());
3216
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003217 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003219 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003221 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003223 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 if (PRE->isExplicitProperty())
3225 return PRE->getExplicitProperty();
3226 // It could be messaging both getter and setter as in:
3227 // ++myobj.myprop;
3228 // in which case prefer to associate the setter since it is less obvious
3229 // from inspecting the source that the setter is going to get called.
3230 if (PRE->isMessagingSetter())
3231 return PRE->getImplicitPropertySetter();
3232 return PRE->getImplicitPropertyGetter();
3233 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003234 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003236 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 if (Expr *Src = OVE->getSourceExpr())
3238 return getDeclFromExpr(Src);
3239
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003240 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003242 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 if (!CE->isElidable())
3244 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003245 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 return OME->getMethodDecl();
3247
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003248 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003250 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003251 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3252 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003253 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3255 isa<ParmVarDecl>(SizeOfPack->getPack()))
3256 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003257
3258 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259}
3260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003261static SourceLocation getLocationFromExpr(const Expr *E) {
3262 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 return getLocationFromExpr(CE->getSubExpr());
3264
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003265 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003267 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003269 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003271 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003273 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003275 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 return PropRef->getLocation();
3277
3278 return E->getLocStart();
3279}
3280
3281extern "C" {
3282
3283unsigned clang_visitChildren(CXCursor parent,
3284 CXCursorVisitor visitor,
3285 CXClientData client_data) {
3286 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3287 /*VisitPreprocessorLast=*/false);
3288 return CursorVis.VisitChildren(parent);
3289}
3290
3291#ifndef __has_feature
3292#define __has_feature(x) 0
3293#endif
3294#if __has_feature(blocks)
3295typedef enum CXChildVisitResult
3296 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3297
3298static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3299 CXClientData client_data) {
3300 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3301 return block(cursor, parent);
3302}
3303#else
3304// If we are compiled with a compiler that doesn't have native blocks support,
3305// define and call the block manually, so the
3306typedef struct _CXChildVisitResult
3307{
3308 void *isa;
3309 int flags;
3310 int reserved;
3311 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3312 CXCursor);
3313} *CXCursorVisitorBlock;
3314
3315static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3316 CXClientData client_data) {
3317 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3318 return block->invoke(block, cursor, parent);
3319}
3320#endif
3321
3322
3323unsigned clang_visitChildrenWithBlock(CXCursor parent,
3324 CXCursorVisitorBlock block) {
3325 return clang_visitChildren(parent, visitWithBlock, block);
3326}
3327
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003328static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003330 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003334 if (const ObjCPropertyImplDecl *PropImpl =
3335 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003339 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3351 // and returns different names. NamedDecl returns the class name and
3352 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003353 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003356 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003357
3358 SmallString<1024> S;
3359 llvm::raw_svector_ostream os(S);
3360 ND->printName(os);
3361
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363}
3364
3365CXString clang_getCursorSpelling(CXCursor C) {
3366 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003367 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003368
3369 if (clang_isReference(C.kind)) {
3370 switch (C.kind) {
3371 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003372 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003373 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 }
3375 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003376 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003377 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003380 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003382 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 }
3384 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003385 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003389 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 assert(Type && "Missing type decl");
3391
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 getAsString());
3394 }
3395 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003396 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 assert(Template && "Missing template decl");
3398
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003399 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
3401
3402 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003403 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 assert(NS && "Missing namespace decl");
3405
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003406 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 }
3408
3409 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003410 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 assert(Field && "Missing member decl");
3412
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003413 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 }
3415
3416 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003417 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 assert(Label && "Missing label");
3419
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 case CXCursor_OverloadedDeclRef: {
3424 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3426 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003427 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003428 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003430 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003431 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 OverloadedTemplateStorage *Ovl
3433 = Storage.get<OverloadedTemplateStorage*>();
3434 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003435 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003436 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 }
3438
3439 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003440 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 assert(Var && "Missing variable decl");
3442
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 }
3445
3446 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003447 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449 }
3450
3451 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003452 const Expr *E = getCursorExpr(C);
3453
3454 if (C.kind == CXCursor_ObjCStringLiteral ||
3455 C.kind == CXCursor_StringLiteral) {
3456 const StringLiteral *SLit;
3457 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3458 SLit = OSL->getString();
3459 } else {
3460 SLit = cast<StringLiteral>(E);
3461 }
3462 SmallString<256> Buf;
3463 llvm::raw_svector_ostream OS(Buf);
3464 SLit->outputString(OS);
3465 return cxstring::createDup(OS.str());
3466 }
3467
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003468 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 if (D)
3470 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003471 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 }
3473
3474 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003475 const Stmt *S = getCursorStmt(C);
3476 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003477 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003479 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481
3482 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 ->getNameStart());
3485
3486 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003487 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 ->getNameStart());
3489
3490 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003491 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003492
3493 if (clang_isDeclaration(C.kind))
3494 return getDeclSpelling(getCursorDecl(C));
3495
3496 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003497 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003498 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 }
3500
3501 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003502 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003503 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003506 if (C.kind == CXCursor_PackedAttr) {
3507 return cxstring::createRef("packed");
3508 }
3509
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003510 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003511}
3512
3513CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3514 unsigned pieceIndex,
3515 unsigned options) {
3516 if (clang_Cursor_isNull(C))
3517 return clang_getNullRange();
3518
3519 ASTContext &Ctx = getCursorContext(C);
3520
3521 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003522 const Stmt *S = getCursorStmt(C);
3523 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 if (pieceIndex > 0)
3525 return clang_getNullRange();
3526 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3527 }
3528
3529 return clang_getNullRange();
3530 }
3531
3532 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003533 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3535 if (pieceIndex >= ME->getNumSelectorLocs())
3536 return clang_getNullRange();
3537 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3538 }
3539 }
3540
3541 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3542 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3545 if (pieceIndex >= MD->getNumSelectorLocs())
3546 return clang_getNullRange();
3547 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3548 }
3549 }
3550
3551 if (C.kind == CXCursor_ObjCCategoryDecl ||
3552 C.kind == CXCursor_ObjCCategoryImplDecl) {
3553 if (pieceIndex > 0)
3554 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3557 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003558 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3560 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3561 }
3562
3563 if (C.kind == CXCursor_ModuleImportDecl) {
3564 if (pieceIndex > 0)
3565 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003566 if (const ImportDecl *ImportD =
3567 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3569 if (!Locs.empty())
3570 return cxloc::translateSourceRange(Ctx,
3571 SourceRange(Locs.front(), Locs.back()));
3572 }
3573 return clang_getNullRange();
3574 }
3575
3576 // FIXME: A CXCursor_InclusionDirective should give the location of the
3577 // filename, but we don't keep track of this.
3578
3579 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3580 // but we don't keep track of this.
3581
3582 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3583 // but we don't keep track of this.
3584
3585 // Default handling, give the location of the cursor.
3586
3587 if (pieceIndex > 0)
3588 return clang_getNullRange();
3589
3590 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3591 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3592 return cxloc::translateSourceRange(Ctx, Loc);
3593}
3594
3595CXString clang_getCursorDisplayName(CXCursor C) {
3596 if (!clang_isDeclaration(C.kind))
3597 return clang_getCursorSpelling(C);
3598
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003599 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602
3603 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003604 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 D = FunTmpl->getTemplatedDecl();
3606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003607 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 SmallString<64> Str;
3609 llvm::raw_svector_ostream OS(Str);
3610 OS << *Function;
3611 if (Function->getPrimaryTemplate())
3612 OS << "<>";
3613 OS << "(";
3614 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3615 if (I)
3616 OS << ", ";
3617 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3618 }
3619
3620 if (Function->isVariadic()) {
3621 if (Function->getNumParams())
3622 OS << ", ";
3623 OS << "...";
3624 }
3625 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003626 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 }
3628
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003629 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 SmallString<64> Str;
3631 llvm::raw_svector_ostream OS(Str);
3632 OS << *ClassTemplate;
3633 OS << "<";
3634 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3635 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3636 if (I)
3637 OS << ", ";
3638
3639 NamedDecl *Param = Params->getParam(I);
3640 if (Param->getIdentifier()) {
3641 OS << Param->getIdentifier()->getName();
3642 continue;
3643 }
3644
3645 // There is no parameter name, which makes this tricky. Try to come up
3646 // with something useful that isn't too long.
3647 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3648 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3649 else if (NonTypeTemplateParmDecl *NTTP
3650 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3651 OS << NTTP->getType().getAsString(Policy);
3652 else
3653 OS << "template<...> class";
3654 }
3655
3656 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003657 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003660 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3662 // If the type was explicitly written, use that.
3663 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003664 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003665
Benjamin Kramer9170e912013-02-22 15:46:01 +00003666 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 llvm::raw_svector_ostream OS(Str);
3668 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003669 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 ClassSpec->getTemplateArgs().data(),
3671 ClassSpec->getTemplateArgs().size(),
3672 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003673 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
3676 return clang_getCursorSpelling(C);
3677}
3678
3679CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3680 switch (Kind) {
3681 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003809 case CXCursor_ObjCSelfExpr:
3810 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003899 case CXCursor_SEHLeaveStmt:
3900 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003929 case CXCursor_PackedAttr:
3930 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003931 case CXCursor_PureAttr:
3932 return cxstring::createRef("attribute(pure)");
3933 case CXCursor_ConstAttr:
3934 return cxstring::createRef("attribute(const)");
3935 case CXCursor_NoDuplicateAttr:
3936 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003937 case CXCursor_CUDAConstantAttr:
3938 return cxstring::createRef("attribute(constant)");
3939 case CXCursor_CUDADeviceAttr:
3940 return cxstring::createRef("attribute(device)");
3941 case CXCursor_CUDAGlobalAttr:
3942 return cxstring::createRef("attribute(global)");
3943 case CXCursor_CUDAHostAttr:
3944 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003993 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003994 return cxstring::createRef("OMPParallelDirective");
3995 case CXCursor_OMPSimdDirective:
3996 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003997 case CXCursor_OMPForDirective:
3998 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003999 case CXCursor_OMPSectionsDirective:
4000 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004001 case CXCursor_OMPSectionDirective:
4002 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004003 case CXCursor_OMPSingleDirective:
4004 return cxstring::createRef("OMPSingleDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004005 case CXCursor_OMPParallelForDirective:
4006 return cxstring::createRef("OMPParallelForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 }
4008
4009 llvm_unreachable("Unhandled CXCursorKind");
4010}
4011
4012struct GetCursorData {
4013 SourceLocation TokenBeginLoc;
4014 bool PointsAtMacroArgExpansion;
4015 bool VisitedObjCPropertyImplDecl;
4016 SourceLocation VisitedDeclaratorDeclStartLoc;
4017 CXCursor &BestCursor;
4018
4019 GetCursorData(SourceManager &SM,
4020 SourceLocation tokenBegin, CXCursor &outputCursor)
4021 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4022 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4023 VisitedObjCPropertyImplDecl = false;
4024 }
4025};
4026
4027static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4028 CXCursor parent,
4029 CXClientData client_data) {
4030 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4031 CXCursor *BestCursor = &Data->BestCursor;
4032
4033 // If we point inside a macro argument we should provide info of what the
4034 // token is so use the actual cursor, don't replace it with a macro expansion
4035 // cursor.
4036 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4037 return CXChildVisit_Recurse;
4038
4039 if (clang_isDeclaration(cursor.kind)) {
4040 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004041 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4043 if (MD->isImplicit())
4044 return CXChildVisit_Break;
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4048 // Check that when we have multiple @class references in the same line,
4049 // that later ones do not override the previous ones.
4050 // If we have:
4051 // @class Foo, Bar;
4052 // source ranges for both start at '@', so 'Bar' will end up overriding
4053 // 'Foo' even though the cursor location was at 'Foo'.
4054 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4055 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004056 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4058 if (PrevID != ID &&
4059 !PrevID->isThisDeclarationADefinition() &&
4060 !ID->isThisDeclarationADefinition())
4061 return CXChildVisit_Break;
4062 }
4063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004064 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4066 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4067 // Check that when we have multiple declarators in the same line,
4068 // that later ones do not override the previous ones.
4069 // If we have:
4070 // int Foo, Bar;
4071 // source ranges for both start at 'int', so 'Bar' will end up overriding
4072 // 'Foo' even though the cursor location was at 'Foo'.
4073 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4074 return CXChildVisit_Break;
4075 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4076
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004077 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4079 (void)PropImp;
4080 // Check that when we have multiple @synthesize in the same line,
4081 // that later ones do not override the previous ones.
4082 // If we have:
4083 // @synthesize Foo, Bar;
4084 // source ranges for both start at '@', so 'Bar' will end up overriding
4085 // 'Foo' even though the cursor location was at 'Foo'.
4086 if (Data->VisitedObjCPropertyImplDecl)
4087 return CXChildVisit_Break;
4088 Data->VisitedObjCPropertyImplDecl = true;
4089 }
4090 }
4091
4092 if (clang_isExpression(cursor.kind) &&
4093 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004094 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 // Avoid having the cursor of an expression replace the declaration cursor
4096 // when the expression source range overlaps the declaration range.
4097 // This can happen for C++ constructor expressions whose range generally
4098 // include the variable declaration, e.g.:
4099 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4100 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4101 D->getLocation() == Data->TokenBeginLoc)
4102 return CXChildVisit_Break;
4103 }
4104 }
4105
4106 // If our current best cursor is the construction of a temporary object,
4107 // don't replace that cursor with a type reference, because we want
4108 // clang_getCursor() to point at the constructor.
4109 if (clang_isExpression(BestCursor->kind) &&
4110 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4111 cursor.kind == CXCursor_TypeRef) {
4112 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4113 // as having the actual point on the type reference.
4114 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4115 return CXChildVisit_Recurse;
4116 }
4117
4118 *BestCursor = cursor;
4119 return CXChildVisit_Recurse;
4120}
4121
4122CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004123 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004124 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004126 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004127
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004128 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4130
4131 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4132 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4133
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004134 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 CXFile SearchFile;
4136 unsigned SearchLine, SearchColumn;
4137 CXFile ResultFile;
4138 unsigned ResultLine, ResultColumn;
4139 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4140 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4141 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004142
4143 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4144 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004145 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004146 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 SearchFileName = clang_getFileName(SearchFile);
4148 ResultFileName = clang_getFileName(ResultFile);
4149 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4150 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004151 *Log << llvm::format("(%s:%d:%d) = %s",
4152 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4153 clang_getCString(KindSpelling))
4154 << llvm::format("(%s:%d:%d):%s%s",
4155 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4156 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 clang_disposeString(SearchFileName);
4158 clang_disposeString(ResultFileName);
4159 clang_disposeString(KindSpelling);
4160 clang_disposeString(USR);
4161
4162 CXCursor Definition = clang_getCursorDefinition(Result);
4163 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4164 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4165 CXString DefinitionKindSpelling
4166 = clang_getCursorKindSpelling(Definition.kind);
4167 CXFile DefinitionFile;
4168 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004169 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004170 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004172 *Log << llvm::format(" -> %s(%s:%d:%d)",
4173 clang_getCString(DefinitionKindSpelling),
4174 clang_getCString(DefinitionFileName),
4175 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 clang_disposeString(DefinitionFileName);
4177 clang_disposeString(DefinitionKindSpelling);
4178 }
4179 }
4180
4181 return Result;
4182}
4183
4184CXCursor clang_getNullCursor(void) {
4185 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4186}
4187
4188unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004189 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4190 // can't set consistently. For example, when visiting a DeclStmt we will set
4191 // it but we don't set it on the result of clang_getCursorDefinition for
4192 // a reference of the same declaration.
4193 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4194 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4195 // to provide that kind of info.
4196 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004197 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004198 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004199 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004200
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 return X == Y;
4202}
4203
4204unsigned clang_hashCursor(CXCursor C) {
4205 unsigned Index = 0;
4206 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4207 Index = 1;
4208
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 std::make_pair(C.kind, C.data[Index]));
4211}
4212
4213unsigned clang_isInvalid(enum CXCursorKind K) {
4214 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4215}
4216
4217unsigned clang_isDeclaration(enum CXCursorKind K) {
4218 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4219 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4220}
4221
4222unsigned clang_isReference(enum CXCursorKind K) {
4223 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4224}
4225
4226unsigned clang_isExpression(enum CXCursorKind K) {
4227 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4228}
4229
4230unsigned clang_isStatement(enum CXCursorKind K) {
4231 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4232}
4233
4234unsigned clang_isAttribute(enum CXCursorKind K) {
4235 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4236}
4237
4238unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4239 return K == CXCursor_TranslationUnit;
4240}
4241
4242unsigned clang_isPreprocessing(enum CXCursorKind K) {
4243 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4244}
4245
4246unsigned clang_isUnexposed(enum CXCursorKind K) {
4247 switch (K) {
4248 case CXCursor_UnexposedDecl:
4249 case CXCursor_UnexposedExpr:
4250 case CXCursor_UnexposedStmt:
4251 case CXCursor_UnexposedAttr:
4252 return true;
4253 default:
4254 return false;
4255 }
4256}
4257
4258CXCursorKind clang_getCursorKind(CXCursor C) {
4259 return C.kind;
4260}
4261
4262CXSourceLocation clang_getCursorLocation(CXCursor C) {
4263 if (clang_isReference(C.kind)) {
4264 switch (C.kind) {
4265 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004266 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 = getCursorObjCSuperClassRef(C);
4268 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4269 }
4270
4271 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004272 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 = getCursorObjCProtocolRef(C);
4274 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4275 }
4276
4277 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004278 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 = getCursorObjCClassRef(C);
4280 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4281 }
4282
4283 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004284 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4286 }
4287
4288 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004289 std::pair<const TemplateDecl *, SourceLocation> P =
4290 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4292 }
4293
4294 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004295 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4297 }
4298
4299 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004300 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4302 }
4303
4304 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004305 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4307 }
4308
4309 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004310 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 if (!BaseSpec)
4312 return clang_getNullLocation();
4313
4314 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4315 return cxloc::translateSourceLocation(getCursorContext(C),
4316 TSInfo->getTypeLoc().getBeginLoc());
4317
4318 return cxloc::translateSourceLocation(getCursorContext(C),
4319 BaseSpec->getLocStart());
4320 }
4321
4322 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004323 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4325 }
4326
4327 case CXCursor_OverloadedDeclRef:
4328 return cxloc::translateSourceLocation(getCursorContext(C),
4329 getCursorOverloadedDeclRef(C).second);
4330
4331 default:
4332 // FIXME: Need a way to enumerate all non-reference cases.
4333 llvm_unreachable("Missed a reference kind");
4334 }
4335 }
4336
4337 if (clang_isExpression(C.kind))
4338 return cxloc::translateSourceLocation(getCursorContext(C),
4339 getLocationFromExpr(getCursorExpr(C)));
4340
4341 if (clang_isStatement(C.kind))
4342 return cxloc::translateSourceLocation(getCursorContext(C),
4343 getCursorStmt(C)->getLocStart());
4344
4345 if (C.kind == CXCursor_PreprocessingDirective) {
4346 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4347 return cxloc::translateSourceLocation(getCursorContext(C), L);
4348 }
4349
4350 if (C.kind == CXCursor_MacroExpansion) {
4351 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004352 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 return cxloc::translateSourceLocation(getCursorContext(C), L);
4354 }
4355
4356 if (C.kind == CXCursor_MacroDefinition) {
4357 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4358 return cxloc::translateSourceLocation(getCursorContext(C), L);
4359 }
4360
4361 if (C.kind == CXCursor_InclusionDirective) {
4362 SourceLocation L
4363 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4364 return cxloc::translateSourceLocation(getCursorContext(C), L);
4365 }
4366
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004367 if (clang_isAttribute(C.kind)) {
4368 SourceLocation L
4369 = cxcursor::getCursorAttr(C)->getLocation();
4370 return cxloc::translateSourceLocation(getCursorContext(C), L);
4371 }
4372
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 if (!clang_isDeclaration(C.kind))
4374 return clang_getNullLocation();
4375
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004376 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 if (!D)
4378 return clang_getNullLocation();
4379
4380 SourceLocation Loc = D->getLocation();
4381 // FIXME: Multiple variables declared in a single declaration
4382 // currently lack the information needed to correctly determine their
4383 // ranges when accounting for the type-specifier. We use context
4384 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4385 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004386 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 if (!cxcursor::isFirstInDeclGroup(C))
4388 Loc = VD->getLocation();
4389 }
4390
4391 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004392 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 Loc = MD->getSelectorStartLoc();
4394
4395 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4396}
4397
4398} // end extern "C"
4399
4400CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4401 assert(TU);
4402
4403 // Guard against an invalid SourceLocation, or we may assert in one
4404 // of the following calls.
4405 if (SLoc.isInvalid())
4406 return clang_getNullCursor();
4407
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004408 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004409
4410 // Translate the given source location to make it point at the beginning of
4411 // the token under the cursor.
4412 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4413 CXXUnit->getASTContext().getLangOpts());
4414
4415 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4416 if (SLoc.isValid()) {
4417 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4418 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4419 /*VisitPreprocessorLast=*/true,
4420 /*VisitIncludedEntities=*/false,
4421 SourceLocation(SLoc));
4422 CursorVis.visitFileRegion();
4423 }
4424
4425 return Result;
4426}
4427
4428static SourceRange getRawCursorExtent(CXCursor C) {
4429 if (clang_isReference(C.kind)) {
4430 switch (C.kind) {
4431 case CXCursor_ObjCSuperClassRef:
4432 return getCursorObjCSuperClassRef(C).second;
4433
4434 case CXCursor_ObjCProtocolRef:
4435 return getCursorObjCProtocolRef(C).second;
4436
4437 case CXCursor_ObjCClassRef:
4438 return getCursorObjCClassRef(C).second;
4439
4440 case CXCursor_TypeRef:
4441 return getCursorTypeRef(C).second;
4442
4443 case CXCursor_TemplateRef:
4444 return getCursorTemplateRef(C).second;
4445
4446 case CXCursor_NamespaceRef:
4447 return getCursorNamespaceRef(C).second;
4448
4449 case CXCursor_MemberRef:
4450 return getCursorMemberRef(C).second;
4451
4452 case CXCursor_CXXBaseSpecifier:
4453 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4454
4455 case CXCursor_LabelRef:
4456 return getCursorLabelRef(C).second;
4457
4458 case CXCursor_OverloadedDeclRef:
4459 return getCursorOverloadedDeclRef(C).second;
4460
4461 case CXCursor_VariableRef:
4462 return getCursorVariableRef(C).second;
4463
4464 default:
4465 // FIXME: Need a way to enumerate all non-reference cases.
4466 llvm_unreachable("Missed a reference kind");
4467 }
4468 }
4469
4470 if (clang_isExpression(C.kind))
4471 return getCursorExpr(C)->getSourceRange();
4472
4473 if (clang_isStatement(C.kind))
4474 return getCursorStmt(C)->getSourceRange();
4475
4476 if (clang_isAttribute(C.kind))
4477 return getCursorAttr(C)->getRange();
4478
4479 if (C.kind == CXCursor_PreprocessingDirective)
4480 return cxcursor::getCursorPreprocessingDirective(C);
4481
4482 if (C.kind == CXCursor_MacroExpansion) {
4483 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004484 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 return TU->mapRangeFromPreamble(Range);
4486 }
4487
4488 if (C.kind == CXCursor_MacroDefinition) {
4489 ASTUnit *TU = getCursorASTUnit(C);
4490 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4491 return TU->mapRangeFromPreamble(Range);
4492 }
4493
4494 if (C.kind == CXCursor_InclusionDirective) {
4495 ASTUnit *TU = getCursorASTUnit(C);
4496 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4497 return TU->mapRangeFromPreamble(Range);
4498 }
4499
4500 if (C.kind == CXCursor_TranslationUnit) {
4501 ASTUnit *TU = getCursorASTUnit(C);
4502 FileID MainID = TU->getSourceManager().getMainFileID();
4503 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4504 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4505 return SourceRange(Start, End);
4506 }
4507
4508 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004509 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 if (!D)
4511 return SourceRange();
4512
4513 SourceRange R = D->getSourceRange();
4514 // FIXME: Multiple variables declared in a single declaration
4515 // currently lack the information needed to correctly determine their
4516 // ranges when accounting for the type-specifier. We use context
4517 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4518 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 if (!cxcursor::isFirstInDeclGroup(C))
4521 R.setBegin(VD->getLocation());
4522 }
4523 return R;
4524 }
4525 return SourceRange();
4526}
4527
4528/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4529/// the decl-specifier-seq for declarations.
4530static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4531 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 if (!D)
4534 return SourceRange();
4535
4536 SourceRange R = D->getSourceRange();
4537
4538 // Adjust the start of the location for declarations preceded by
4539 // declaration specifiers.
4540 SourceLocation StartLoc;
4541 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4542 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4543 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4546 StartLoc = TI->getTypeLoc().getLocStart();
4547 }
4548
4549 if (StartLoc.isValid() && R.getBegin().isValid() &&
4550 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4551 R.setBegin(StartLoc);
4552
4553 // FIXME: Multiple variables declared in a single declaration
4554 // currently lack the information needed to correctly determine their
4555 // ranges when accounting for the type-specifier. We use context
4556 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4557 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004558 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 if (!cxcursor::isFirstInDeclGroup(C))
4560 R.setBegin(VD->getLocation());
4561 }
4562
4563 return R;
4564 }
4565
4566 return getRawCursorExtent(C);
4567}
4568
4569extern "C" {
4570
4571CXSourceRange clang_getCursorExtent(CXCursor C) {
4572 SourceRange R = getRawCursorExtent(C);
4573 if (R.isInvalid())
4574 return clang_getNullRange();
4575
4576 return cxloc::translateSourceRange(getCursorContext(C), R);
4577}
4578
4579CXCursor clang_getCursorReferenced(CXCursor C) {
4580 if (clang_isInvalid(C.kind))
4581 return clang_getNullCursor();
4582
4583 CXTranslationUnit tu = getCursorTU(C);
4584 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004585 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 if (!D)
4587 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004588 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004590 if (const ObjCPropertyImplDecl *PropImpl =
4591 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4593 return MakeCXCursor(Property, tu);
4594
4595 return C;
4596 }
4597
4598 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004599 const Expr *E = getCursorExpr(C);
4600 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 if (D) {
4602 CXCursor declCursor = MakeCXCursor(D, tu);
4603 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4604 declCursor);
4605 return declCursor;
4606 }
4607
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004608 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 return MakeCursorOverloadedDeclRef(Ovl, tu);
4610
4611 return clang_getNullCursor();
4612 }
4613
4614 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004615 const Stmt *S = getCursorStmt(C);
4616 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 if (LabelDecl *label = Goto->getLabel())
4618 if (LabelStmt *labelS = label->getStmt())
4619 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4620
4621 return clang_getNullCursor();
4622 }
4623
4624 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004625 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 return MakeMacroDefinitionCursor(Def, tu);
4627 }
4628
4629 if (!clang_isReference(C.kind))
4630 return clang_getNullCursor();
4631
4632 switch (C.kind) {
4633 case CXCursor_ObjCSuperClassRef:
4634 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4635
4636 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004637 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4638 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 return MakeCXCursor(Def, tu);
4640
4641 return MakeCXCursor(Prot, tu);
4642 }
4643
4644 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004645 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4646 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 return MakeCXCursor(Def, tu);
4648
4649 return MakeCXCursor(Class, tu);
4650 }
4651
4652 case CXCursor_TypeRef:
4653 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4654
4655 case CXCursor_TemplateRef:
4656 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4657
4658 case CXCursor_NamespaceRef:
4659 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4660
4661 case CXCursor_MemberRef:
4662 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4663
4664 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004665 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4667 tu ));
4668 }
4669
4670 case CXCursor_LabelRef:
4671 // FIXME: We end up faking the "parent" declaration here because we
4672 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004673 return MakeCXCursor(getCursorLabelRef(C).first,
4674 cxtu::getASTUnit(tu)->getASTContext()
4675 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 tu);
4677
4678 case CXCursor_OverloadedDeclRef:
4679 return C;
4680
4681 case CXCursor_VariableRef:
4682 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4683
4684 default:
4685 // We would prefer to enumerate all non-reference cursor kinds here.
4686 llvm_unreachable("Unhandled reference cursor kind");
4687 }
4688}
4689
4690CXCursor clang_getCursorDefinition(CXCursor C) {
4691 if (clang_isInvalid(C.kind))
4692 return clang_getNullCursor();
4693
4694 CXTranslationUnit TU = getCursorTU(C);
4695
4696 bool WasReference = false;
4697 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4698 C = clang_getCursorReferenced(C);
4699 WasReference = true;
4700 }
4701
4702 if (C.kind == CXCursor_MacroExpansion)
4703 return clang_getCursorReferenced(C);
4704
4705 if (!clang_isDeclaration(C.kind))
4706 return clang_getNullCursor();
4707
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004708 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 if (!D)
4710 return clang_getNullCursor();
4711
4712 switch (D->getKind()) {
4713 // Declaration kinds that don't really separate the notions of
4714 // declaration and definition.
4715 case Decl::Namespace:
4716 case Decl::Typedef:
4717 case Decl::TypeAlias:
4718 case Decl::TypeAliasTemplate:
4719 case Decl::TemplateTypeParm:
4720 case Decl::EnumConstant:
4721 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004722 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case Decl::IndirectField:
4724 case Decl::ObjCIvar:
4725 case Decl::ObjCAtDefsField:
4726 case Decl::ImplicitParam:
4727 case Decl::ParmVar:
4728 case Decl::NonTypeTemplateParm:
4729 case Decl::TemplateTemplateParm:
4730 case Decl::ObjCCategoryImpl:
4731 case Decl::ObjCImplementation:
4732 case Decl::AccessSpec:
4733 case Decl::LinkageSpec:
4734 case Decl::ObjCPropertyImpl:
4735 case Decl::FileScopeAsm:
4736 case Decl::StaticAssert:
4737 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004738 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case Decl::Label: // FIXME: Is this right??
4740 case Decl::ClassScopeFunctionSpecialization:
4741 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004742 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 return C;
4744
4745 // Declaration kinds that don't make any sense here, but are
4746 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004747 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 case Decl::TranslationUnit:
4749 break;
4750
4751 // Declaration kinds for which the definition is not resolvable.
4752 case Decl::UnresolvedUsingTypename:
4753 case Decl::UnresolvedUsingValue:
4754 break;
4755
4756 case Decl::UsingDirective:
4757 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4758 TU);
4759
4760 case Decl::NamespaceAlias:
4761 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4762
4763 case Decl::Enum:
4764 case Decl::Record:
4765 case Decl::CXXRecord:
4766 case Decl::ClassTemplateSpecialization:
4767 case Decl::ClassTemplatePartialSpecialization:
4768 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4769 return MakeCXCursor(Def, TU);
4770 return clang_getNullCursor();
4771
4772 case Decl::Function:
4773 case Decl::CXXMethod:
4774 case Decl::CXXConstructor:
4775 case Decl::CXXDestructor:
4776 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004777 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004779 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 return clang_getNullCursor();
4781 }
4782
Larisse Voufo39a1e502013-08-06 01:03:05 +00004783 case Decl::Var:
4784 case Decl::VarTemplateSpecialization:
4785 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return MakeCXCursor(Def, TU);
4789 return clang_getNullCursor();
4790 }
4791
4792 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004793 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4795 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4796 return clang_getNullCursor();
4797 }
4798
4799 case Decl::ClassTemplate: {
4800 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4801 ->getDefinition())
4802 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4803 TU);
4804 return clang_getNullCursor();
4805 }
4806
Larisse Voufo39a1e502013-08-06 01:03:05 +00004807 case Decl::VarTemplate: {
4808 if (VarDecl *Def =
4809 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4810 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4811 return clang_getNullCursor();
4812 }
4813
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 case Decl::Using:
4815 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4816 D->getLocation(), TU);
4817
4818 case Decl::UsingShadow:
4819 return clang_getCursorDefinition(
4820 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4821 TU));
4822
4823 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004824 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 if (Method->isThisDeclarationADefinition())
4826 return C;
4827
4828 // Dig out the method definition in the associated
4829 // @implementation, if we have it.
4830 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4833 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4834 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4835 Method->isInstanceMethod()))
4836 if (Def->isThisDeclarationADefinition())
4837 return MakeCXCursor(Def, TU);
4838
4839 return clang_getNullCursor();
4840 }
4841
4842 case Decl::ObjCCategory:
4843 if (ObjCCategoryImplDecl *Impl
4844 = cast<ObjCCategoryDecl>(D)->getImplementation())
4845 return MakeCXCursor(Impl, TU);
4846 return clang_getNullCursor();
4847
4848 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 return MakeCXCursor(Def, TU);
4851 return clang_getNullCursor();
4852
4853 case Decl::ObjCInterface: {
4854 // There are two notions of a "definition" for an Objective-C
4855 // class: the interface and its implementation. When we resolved a
4856 // reference to an Objective-C class, produce the @interface as
4857 // the definition; when we were provided with the interface,
4858 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 return MakeCXCursor(Def, TU);
4863 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4864 return MakeCXCursor(Impl, TU);
4865 return clang_getNullCursor();
4866 }
4867
4868 case Decl::ObjCProperty:
4869 // FIXME: We don't really know where to find the
4870 // ObjCPropertyImplDecls that implement this property.
4871 return clang_getNullCursor();
4872
4873 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 return MakeCXCursor(Def, TU);
4878
4879 return clang_getNullCursor();
4880
4881 case Decl::Friend:
4882 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4883 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4884 return clang_getNullCursor();
4885
4886 case Decl::FriendTemplate:
4887 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4888 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4889 return clang_getNullCursor();
4890 }
4891
4892 return clang_getNullCursor();
4893}
4894
4895unsigned clang_isCursorDefinition(CXCursor C) {
4896 if (!clang_isDeclaration(C.kind))
4897 return 0;
4898
4899 return clang_getCursorDefinition(C) == C;
4900}
4901
4902CXCursor clang_getCanonicalCursor(CXCursor C) {
4903 if (!clang_isDeclaration(C.kind))
4904 return C;
4905
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004906 if (const Decl *D = getCursorDecl(C)) {
4907 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4909 return MakeCXCursor(CatD, getCursorTU(C));
4910
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4912 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 return MakeCXCursor(IFD, getCursorTU(C));
4914
4915 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4916 }
4917
4918 return C;
4919}
4920
4921int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4922 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4923}
4924
4925unsigned clang_getNumOverloadedDecls(CXCursor C) {
4926 if (C.kind != CXCursor_OverloadedDeclRef)
4927 return 0;
4928
4929 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004930 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 return E->getNumDecls();
4932
4933 if (OverloadedTemplateStorage *S
4934 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4935 return S->size();
4936
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 const Decl *D = Storage.get<const Decl *>();
4938 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004939 return Using->shadow_size();
4940
4941 return 0;
4942}
4943
4944CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4945 if (cursor.kind != CXCursor_OverloadedDeclRef)
4946 return clang_getNullCursor();
4947
4948 if (index >= clang_getNumOverloadedDecls(cursor))
4949 return clang_getNullCursor();
4950
4951 CXTranslationUnit TU = getCursorTU(cursor);
4952 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004953 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 return MakeCXCursor(E->decls_begin()[index], TU);
4955
4956 if (OverloadedTemplateStorage *S
4957 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4958 return MakeCXCursor(S->begin()[index], TU);
4959
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004960 const Decl *D = Storage.get<const Decl *>();
4961 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 // FIXME: This is, unfortunately, linear time.
4963 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4964 std::advance(Pos, index);
4965 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4966 }
4967
4968 return clang_getNullCursor();
4969}
4970
4971void clang_getDefinitionSpellingAndExtent(CXCursor C,
4972 const char **startBuf,
4973 const char **endBuf,
4974 unsigned *startLine,
4975 unsigned *startColumn,
4976 unsigned *endLine,
4977 unsigned *endColumn) {
4978 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004979 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4981
4982 SourceManager &SM = FD->getASTContext().getSourceManager();
4983 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4984 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4985 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4986 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4987 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4988 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4989}
4990
4991
4992CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4993 unsigned PieceIndex) {
4994 RefNamePieces Pieces;
4995
4996 switch (C.kind) {
4997 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004998 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5000 E->getQualifierLoc().getSourceRange());
5001 break;
5002
5003 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005004 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5006 E->getQualifierLoc().getSourceRange(),
5007 E->getOptionalExplicitTemplateArgs());
5008 break;
5009
5010 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005011 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005013 const Expr *Callee = OCE->getCallee();
5014 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 Callee = ICE->getSubExpr();
5016
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005017 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5019 DRE->getQualifierLoc().getSourceRange());
5020 }
5021 break;
5022
5023 default:
5024 break;
5025 }
5026
5027 if (Pieces.empty()) {
5028 if (PieceIndex == 0)
5029 return clang_getCursorExtent(C);
5030 } else if (PieceIndex < Pieces.size()) {
5031 SourceRange R = Pieces[PieceIndex];
5032 if (R.isValid())
5033 return cxloc::translateSourceRange(getCursorContext(C), R);
5034 }
5035
5036 return clang_getNullRange();
5037}
5038
5039void clang_enableStackTraces(void) {
5040 llvm::sys::PrintStackTraceOnErrorSignal();
5041}
5042
5043void clang_executeOnThread(void (*fn)(void*), void *user_data,
5044 unsigned stack_size) {
5045 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5046}
5047
5048} // end: extern "C"
5049
5050//===----------------------------------------------------------------------===//
5051// Token-based Operations.
5052//===----------------------------------------------------------------------===//
5053
5054/* CXToken layout:
5055 * int_data[0]: a CXTokenKind
5056 * int_data[1]: starting token location
5057 * int_data[2]: token length
5058 * int_data[3]: reserved
5059 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5060 * otherwise unused.
5061 */
5062extern "C" {
5063
5064CXTokenKind clang_getTokenKind(CXToken CXTok) {
5065 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5066}
5067
5068CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5069 switch (clang_getTokenKind(CXTok)) {
5070 case CXToken_Identifier:
5071 case CXToken_Keyword:
5072 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005073 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 ->getNameStart());
5075
5076 case CXToken_Literal: {
5077 // We have stashed the starting pointer in the ptr_data field. Use it.
5078 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005079 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 }
5081
5082 case CXToken_Punctuation:
5083 case CXToken_Comment:
5084 break;
5085 }
5086
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005087 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005088 LOG_BAD_TU(TU);
5089 return cxstring::createEmpty();
5090 }
5091
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 // We have to find the starting buffer pointer the hard way, by
5093 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005094 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005096 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005097
5098 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5099 std::pair<FileID, unsigned> LocInfo
5100 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5101 bool Invalid = false;
5102 StringRef Buffer
5103 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5104 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005105 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005106
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005107 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005108}
5109
5110CXSourceLocation clang_getTokenLocation(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_getNullLocation();
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_getNullLocation();
5119
5120 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5121 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5122}
5123
5124CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005126 LOG_BAD_TU(TU);
5127 return clang_getNullRange();
5128 }
5129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 if (!CXXUnit)
5132 return clang_getNullRange();
5133
5134 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5135 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5136}
5137
5138static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5139 SmallVectorImpl<CXToken> &CXTokens) {
5140 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5141 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005142 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005144 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005145
5146 // Cannot tokenize across files.
5147 if (BeginLocInfo.first != EndLocInfo.first)
5148 return;
5149
5150 // Create a lexer
5151 bool Invalid = false;
5152 StringRef Buffer
5153 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5154 if (Invalid)
5155 return;
5156
5157 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5158 CXXUnit->getASTContext().getLangOpts(),
5159 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5160 Lex.SetCommentRetentionState(true);
5161
5162 // Lex tokens until we hit the end of the range.
5163 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5164 Token Tok;
5165 bool previousWasAt = false;
5166 do {
5167 // Lex the next token
5168 Lex.LexFromRawLexer(Tok);
5169 if (Tok.is(tok::eof))
5170 break;
5171
5172 // Initialize the CXToken.
5173 CXToken CXTok;
5174
5175 // - Common fields
5176 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5177 CXTok.int_data[2] = Tok.getLength();
5178 CXTok.int_data[3] = 0;
5179
5180 // - Kind-specific fields
5181 if (Tok.isLiteral()) {
5182 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005183 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 } else if (Tok.is(tok::raw_identifier)) {
5185 // Lookup the identifier to determine whether we have a keyword.
5186 IdentifierInfo *II
5187 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5188
5189 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5190 CXTok.int_data[0] = CXToken_Keyword;
5191 }
5192 else {
5193 CXTok.int_data[0] = Tok.is(tok::identifier)
5194 ? CXToken_Identifier
5195 : CXToken_Keyword;
5196 }
5197 CXTok.ptr_data = II;
5198 } else if (Tok.is(tok::comment)) {
5199 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005200 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 } else {
5202 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005203 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 }
5205 CXTokens.push_back(CXTok);
5206 previousWasAt = Tok.is(tok::at);
5207 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5208}
5209
5210void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5211 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005212 LOG_FUNC_SECTION {
5213 *Log << TU << ' ' << Range;
5214 }
5215
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005217 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 if (NumTokens)
5219 *NumTokens = 0;
5220
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005221 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005222 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005223 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005224 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005225
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005226 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 if (!CXXUnit || !Tokens || !NumTokens)
5228 return;
5229
5230 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5231
5232 SourceRange R = cxloc::translateCXSourceRange(Range);
5233 if (R.isInvalid())
5234 return;
5235
5236 SmallVector<CXToken, 32> CXTokens;
5237 getTokens(CXXUnit, R, CXTokens);
5238
5239 if (CXTokens.empty())
5240 return;
5241
5242 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5243 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5244 *NumTokens = CXTokens.size();
5245}
5246
5247void clang_disposeTokens(CXTranslationUnit TU,
5248 CXToken *Tokens, unsigned NumTokens) {
5249 free(Tokens);
5250}
5251
5252} // end: extern "C"
5253
5254//===----------------------------------------------------------------------===//
5255// Token annotation APIs.
5256//===----------------------------------------------------------------------===//
5257
Guy Benyei11169dd2012-12-18 14:30:41 +00005258static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5259 CXCursor parent,
5260 CXClientData client_data);
5261static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5262 CXClientData client_data);
5263
5264namespace {
5265class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 CXToken *Tokens;
5267 CXCursor *Cursors;
5268 unsigned NumTokens;
5269 unsigned TokIdx;
5270 unsigned PreprocessingTokIdx;
5271 CursorVisitor AnnotateVis;
5272 SourceManager &SrcMgr;
5273 bool HasContextSensitiveKeywords;
5274
5275 struct PostChildrenInfo {
5276 CXCursor Cursor;
5277 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005278 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 unsigned BeforeChildrenTokenIdx;
5280 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005281 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005282
5283 CXToken &getTok(unsigned Idx) {
5284 assert(Idx < NumTokens);
5285 return Tokens[Idx];
5286 }
5287 const CXToken &getTok(unsigned Idx) const {
5288 assert(Idx < NumTokens);
5289 return Tokens[Idx];
5290 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 bool MoreTokens() const { return TokIdx < NumTokens; }
5292 unsigned NextToken() const { return TokIdx; }
5293 void AdvanceToken() { ++TokIdx; }
5294 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005295 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 }
5297 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005298 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 }
5300 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005301 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 }
5303
5304 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005305 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 SourceRange);
5307
5308public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005309 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005310 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005311 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005313 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 AnnotateTokensVisitor, this,
5315 /*VisitPreprocessorLast=*/true,
5316 /*VisitIncludedEntities=*/false,
5317 RegionOfInterest,
5318 /*VisitDeclsOnly=*/false,
5319 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005320 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 HasContextSensitiveKeywords(false) { }
5322
5323 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5324 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5325 bool postVisitChildren(CXCursor cursor);
5326 void AnnotateTokens();
5327
5328 /// \brief Determine whether the annotator saw any cursors that have
5329 /// context-sensitive keywords.
5330 bool hasContextSensitiveKeywords() const {
5331 return HasContextSensitiveKeywords;
5332 }
5333
5334 ~AnnotateTokensWorker() {
5335 assert(PostChildrenInfos.empty());
5336 }
5337};
5338}
5339
5340void AnnotateTokensWorker::AnnotateTokens() {
5341 // Walk the AST within the region of interest, annotating tokens
5342 // along the way.
5343 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005344}
Guy Benyei11169dd2012-12-18 14:30:41 +00005345
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005346static inline void updateCursorAnnotation(CXCursor &Cursor,
5347 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005348 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005350 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005351}
5352
5353/// \brief It annotates and advances tokens with a cursor until the comparison
5354//// between the cursor location and the source range is the same as
5355/// \arg compResult.
5356///
5357/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5358/// Pass RangeOverlap to annotate tokens inside a range.
5359void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5360 RangeComparisonResult compResult,
5361 SourceRange range) {
5362 while (MoreTokens()) {
5363 const unsigned I = NextToken();
5364 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005365 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5366 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005367
5368 SourceLocation TokLoc = GetTokenLoc(I);
5369 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005370 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005371 AdvanceToken();
5372 continue;
5373 }
5374 break;
5375 }
5376}
5377
5378/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005379/// \returns true if it advanced beyond all macro tokens, false otherwise.
5380bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 CXCursor updateC,
5382 RangeComparisonResult compResult,
5383 SourceRange range) {
5384 assert(MoreTokens());
5385 assert(isFunctionMacroToken(NextToken()) &&
5386 "Should be called only for macro arg tokens");
5387
5388 // This works differently than annotateAndAdvanceTokens; because expanded
5389 // macro arguments can have arbitrary translation-unit source order, we do not
5390 // advance the token index one by one until a token fails the range test.
5391 // We only advance once past all of the macro arg tokens if all of them
5392 // pass the range test. If one of them fails we keep the token index pointing
5393 // at the start of the macro arg tokens so that the failing token will be
5394 // annotated by a subsequent annotation try.
5395
5396 bool atLeastOneCompFail = false;
5397
5398 unsigned I = NextToken();
5399 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5400 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5401 if (TokLoc.isFileID())
5402 continue; // not macro arg token, it's parens or comma.
5403 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5404 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5405 Cursors[I] = updateC;
5406 } else
5407 atLeastOneCompFail = true;
5408 }
5409
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005410 if (atLeastOneCompFail)
5411 return false;
5412
5413 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5414 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005415}
5416
5417enum CXChildVisitResult
5418AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 SourceRange cursorRange = getRawCursorExtent(cursor);
5420 if (cursorRange.isInvalid())
5421 return CXChildVisit_Recurse;
5422
5423 if (!HasContextSensitiveKeywords) {
5424 // Objective-C properties can have context-sensitive keywords.
5425 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005426 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5428 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5429 }
5430 // Objective-C methods can have context-sensitive keywords.
5431 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5432 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005433 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5435 if (Method->getObjCDeclQualifier())
5436 HasContextSensitiveKeywords = true;
5437 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005438 for (const auto *P : Method->params()) {
5439 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 HasContextSensitiveKeywords = true;
5441 break;
5442 }
5443 }
5444 }
5445 }
5446 }
5447 // C++ methods can have context-sensitive keywords.
5448 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005449 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5451 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5452 HasContextSensitiveKeywords = true;
5453 }
5454 }
5455 // C++ classes can have context-sensitive keywords.
5456 else if (cursor.kind == CXCursor_StructDecl ||
5457 cursor.kind == CXCursor_ClassDecl ||
5458 cursor.kind == CXCursor_ClassTemplate ||
5459 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005460 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 if (D->hasAttr<FinalAttr>())
5462 HasContextSensitiveKeywords = true;
5463 }
5464 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005465
5466 // Don't override a property annotation with its getter/setter method.
5467 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5468 parent.kind == CXCursor_ObjCPropertyDecl)
5469 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005470
5471 if (clang_isPreprocessing(cursor.kind)) {
5472 // Items in the preprocessing record are kept separate from items in
5473 // declarations, so we keep a separate token index.
5474 unsigned SavedTokIdx = TokIdx;
5475 TokIdx = PreprocessingTokIdx;
5476
5477 // Skip tokens up until we catch up to the beginning of the preprocessing
5478 // entry.
5479 while (MoreTokens()) {
5480 const unsigned I = NextToken();
5481 SourceLocation TokLoc = GetTokenLoc(I);
5482 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5483 case RangeBefore:
5484 AdvanceToken();
5485 continue;
5486 case RangeAfter:
5487 case RangeOverlap:
5488 break;
5489 }
5490 break;
5491 }
5492
5493 // Look at all of the tokens within this range.
5494 while (MoreTokens()) {
5495 const unsigned I = NextToken();
5496 SourceLocation TokLoc = GetTokenLoc(I);
5497 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5498 case RangeBefore:
5499 llvm_unreachable("Infeasible");
5500 case RangeAfter:
5501 break;
5502 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005503 // For macro expansions, just note where the beginning of the macro
5504 // expansion occurs.
5505 if (cursor.kind == CXCursor_MacroExpansion) {
5506 if (TokLoc == cursorRange.getBegin())
5507 Cursors[I] = cursor;
5508 AdvanceToken();
5509 break;
5510 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005511 // We may have already annotated macro names inside macro definitions.
5512 if (Cursors[I].kind != CXCursor_MacroExpansion)
5513 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 continue;
5516 }
5517 break;
5518 }
5519
5520 // Save the preprocessing token index; restore the non-preprocessing
5521 // token index.
5522 PreprocessingTokIdx = TokIdx;
5523 TokIdx = SavedTokIdx;
5524 return CXChildVisit_Recurse;
5525 }
5526
5527 if (cursorRange.isInvalid())
5528 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005529
5530 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 const enum CXCursorKind K = clang_getCursorKind(parent);
5533 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005534 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5535 // Attributes are annotated out-of-order, skip tokens until we reach it.
5536 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005537 ? clang_getNullCursor() : parent;
5538
5539 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5540
5541 // Avoid having the cursor of an expression "overwrite" the annotation of the
5542 // variable declaration that it belongs to.
5543 // This can happen for C++ constructor expressions whose range generally
5544 // include the variable declaration, e.g.:
5545 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005546 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005547 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005548 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 const unsigned I = NextToken();
5550 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5551 E->getLocStart() == D->getLocation() &&
5552 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005553 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 AdvanceToken();
5555 }
5556 }
5557 }
5558
5559 // Before recursing into the children keep some state that we are going
5560 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5561 // extra work after the child nodes are visited.
5562 // Note that we don't call VisitChildren here to avoid traversing statements
5563 // code-recursively which can blow the stack.
5564
5565 PostChildrenInfo Info;
5566 Info.Cursor = cursor;
5567 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005568 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 Info.BeforeChildrenTokenIdx = NextToken();
5570 PostChildrenInfos.push_back(Info);
5571
5572 return CXChildVisit_Recurse;
5573}
5574
5575bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5576 if (PostChildrenInfos.empty())
5577 return false;
5578 const PostChildrenInfo &Info = PostChildrenInfos.back();
5579 if (!clang_equalCursors(Info.Cursor, cursor))
5580 return false;
5581
5582 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5583 const unsigned AfterChildren = NextToken();
5584 SourceRange cursorRange = Info.CursorRange;
5585
5586 // Scan the tokens that are at the end of the cursor, but are not captured
5587 // but the child cursors.
5588 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5589
5590 // Scan the tokens that are at the beginning of the cursor, but are not
5591 // capture by the child cursors.
5592 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5593 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5594 break;
5595
5596 Cursors[I] = cursor;
5597 }
5598
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005599 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5600 // encountered the attribute cursor.
5601 if (clang_isAttribute(cursor.kind))
5602 TokIdx = Info.BeforeReachingCursorIdx;
5603
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 PostChildrenInfos.pop_back();
5605 return false;
5606}
5607
5608static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5609 CXCursor parent,
5610 CXClientData client_data) {
5611 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5612}
5613
5614static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5615 CXClientData client_data) {
5616 return static_cast<AnnotateTokensWorker*>(client_data)->
5617 postVisitChildren(cursor);
5618}
5619
5620namespace {
5621
5622/// \brief Uses the macro expansions in the preprocessing record to find
5623/// and mark tokens that are macro arguments. This info is used by the
5624/// AnnotateTokensWorker.
5625class MarkMacroArgTokensVisitor {
5626 SourceManager &SM;
5627 CXToken *Tokens;
5628 unsigned NumTokens;
5629 unsigned CurIdx;
5630
5631public:
5632 MarkMacroArgTokensVisitor(SourceManager &SM,
5633 CXToken *tokens, unsigned numTokens)
5634 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5635
5636 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5637 if (cursor.kind != CXCursor_MacroExpansion)
5638 return CXChildVisit_Continue;
5639
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005640 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 if (macroRange.getBegin() == macroRange.getEnd())
5642 return CXChildVisit_Continue; // it's not a function macro.
5643
5644 for (; CurIdx < NumTokens; ++CurIdx) {
5645 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5646 macroRange.getBegin()))
5647 break;
5648 }
5649
5650 if (CurIdx == NumTokens)
5651 return CXChildVisit_Break;
5652
5653 for (; CurIdx < NumTokens; ++CurIdx) {
5654 SourceLocation tokLoc = getTokenLoc(CurIdx);
5655 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5656 break;
5657
5658 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5659 }
5660
5661 if (CurIdx == NumTokens)
5662 return CXChildVisit_Break;
5663
5664 return CXChildVisit_Continue;
5665 }
5666
5667private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005668 CXToken &getTok(unsigned Idx) {
5669 assert(Idx < NumTokens);
5670 return Tokens[Idx];
5671 }
5672 const CXToken &getTok(unsigned Idx) const {
5673 assert(Idx < NumTokens);
5674 return Tokens[Idx];
5675 }
5676
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005678 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 }
5680
5681 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5682 // The third field is reserved and currently not used. Use it here
5683 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005684 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 }
5686};
5687
5688} // end anonymous namespace
5689
5690static CXChildVisitResult
5691MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5692 CXClientData client_data) {
5693 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5694 parent);
5695}
5696
5697namespace {
5698 struct clang_annotateTokens_Data {
5699 CXTranslationUnit TU;
5700 ASTUnit *CXXUnit;
5701 CXToken *Tokens;
5702 unsigned NumTokens;
5703 CXCursor *Cursors;
5704 };
5705}
5706
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707/// \brief Used by \c annotatePreprocessorTokens.
5708/// \returns true if lexing was finished, false otherwise.
5709static bool lexNext(Lexer &Lex, Token &Tok,
5710 unsigned &NextIdx, unsigned NumTokens) {
5711 if (NextIdx >= NumTokens)
5712 return true;
5713
5714 ++NextIdx;
5715 Lex.LexFromRawLexer(Tok);
5716 if (Tok.is(tok::eof))
5717 return true;
5718
5719 return false;
5720}
5721
Guy Benyei11169dd2012-12-18 14:30:41 +00005722static void annotatePreprocessorTokens(CXTranslationUnit TU,
5723 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005724 CXCursor *Cursors,
5725 CXToken *Tokens,
5726 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005727 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005728
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005729 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5731 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005732 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005734 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005735
5736 if (BeginLocInfo.first != EndLocInfo.first)
5737 return;
5738
5739 StringRef Buffer;
5740 bool Invalid = false;
5741 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5742 if (Buffer.empty() || Invalid)
5743 return;
5744
5745 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5746 CXXUnit->getASTContext().getLangOpts(),
5747 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5748 Buffer.end());
5749 Lex.SetCommentRetentionState(true);
5750
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 // Lex tokens in raw mode until we hit the end of the range, to avoid
5753 // entering #includes or expanding macros.
5754 while (true) {
5755 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005756 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5757 break;
5758 unsigned TokIdx = NextIdx-1;
5759 assert(Tok.getLocation() ==
5760 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005761
5762 reprocess:
5763 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005764 // We have found a preprocessing directive. Annotate the tokens
5765 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 //
5767 // FIXME: Some simple tests here could identify macro definitions and
5768 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005769
5770 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005771 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5772 break;
5773
Craig Topper69186e72014-06-08 08:38:04 +00005774 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005775 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005776 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5777 break;
5778
5779 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005780 IdentifierInfo &II =
5781 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005782 SourceLocation MappedTokLoc =
5783 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5784 MI = getMacroInfo(II, MappedTokLoc, TU);
5785 }
5786 }
5787
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005788 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005790 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5791 finished = true;
5792 break;
5793 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005794 // If we are in a macro definition, check if the token was ever a
5795 // macro name and annotate it if that's the case.
5796 if (MI) {
5797 SourceLocation SaveLoc = Tok.getLocation();
5798 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5799 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5800 Tok.setLocation(SaveLoc);
5801 if (MacroDef)
5802 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5803 Tok.getLocation(), TU);
5804 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005805 } while (!Tok.isAtStartOfLine());
5806
5807 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5808 assert(TokIdx <= LastIdx);
5809 SourceLocation EndLoc =
5810 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5811 CXCursor Cursor =
5812 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5813
5814 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005815 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005816
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005817 if (finished)
5818 break;
5819 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 }
5822}
5823
5824// This gets run a separate thread to avoid stack blowout.
5825static void clang_annotateTokensImpl(void *UserData) {
5826 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5827 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5828 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5829 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5830 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5831
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005832 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5834 setThreadBackgroundPriority();
5835
5836 // Determine the region of interest, which contains all of the tokens.
5837 SourceRange RegionOfInterest;
5838 RegionOfInterest.setBegin(
5839 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5840 RegionOfInterest.setEnd(
5841 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5842 Tokens[NumTokens-1])));
5843
Guy Benyei11169dd2012-12-18 14:30:41 +00005844 // Relex the tokens within the source range to look for preprocessing
5845 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005846 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005847
5848 // If begin location points inside a macro argument, set it to the expansion
5849 // location so we can have the full context when annotating semantically.
5850 {
5851 SourceManager &SM = CXXUnit->getSourceManager();
5852 SourceLocation Loc =
5853 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5854 if (Loc.isMacroID())
5855 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5856 }
5857
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5859 // Search and mark tokens that are macro argument expansions.
5860 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5861 Tokens, NumTokens);
5862 CursorVisitor MacroArgMarker(TU,
5863 MarkMacroArgTokensVisitorDelegate, &Visitor,
5864 /*VisitPreprocessorLast=*/true,
5865 /*VisitIncludedEntities=*/false,
5866 RegionOfInterest);
5867 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5868 }
5869
5870 // Annotate all of the source locations in the region of interest that map to
5871 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005872 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005873
5874 // FIXME: We use a ridiculous stack size here because the data-recursion
5875 // algorithm uses a large stack frame than the non-data recursive version,
5876 // and AnnotationTokensWorker currently transforms the data-recursion
5877 // algorithm back into a traditional recursion by explicitly calling
5878 // VisitChildren(). We will need to remove this explicit recursive call.
5879 W.AnnotateTokens();
5880
5881 // If we ran into any entities that involve context-sensitive keywords,
5882 // take another pass through the tokens to mark them as such.
5883 if (W.hasContextSensitiveKeywords()) {
5884 for (unsigned I = 0; I != NumTokens; ++I) {
5885 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5886 continue;
5887
5888 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5889 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005890 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5892 if (Property->getPropertyAttributesAsWritten() != 0 &&
5893 llvm::StringSwitch<bool>(II->getName())
5894 .Case("readonly", true)
5895 .Case("assign", true)
5896 .Case("unsafe_unretained", true)
5897 .Case("readwrite", true)
5898 .Case("retain", true)
5899 .Case("copy", true)
5900 .Case("nonatomic", true)
5901 .Case("atomic", true)
5902 .Case("getter", true)
5903 .Case("setter", true)
5904 .Case("strong", true)
5905 .Case("weak", true)
5906 .Default(false))
5907 Tokens[I].int_data[0] = CXToken_Keyword;
5908 }
5909 continue;
5910 }
5911
5912 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5913 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5914 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5915 if (llvm::StringSwitch<bool>(II->getName())
5916 .Case("in", true)
5917 .Case("out", true)
5918 .Case("inout", true)
5919 .Case("oneway", true)
5920 .Case("bycopy", true)
5921 .Case("byref", true)
5922 .Default(false))
5923 Tokens[I].int_data[0] = CXToken_Keyword;
5924 continue;
5925 }
5926
5927 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5928 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5929 Tokens[I].int_data[0] = CXToken_Keyword;
5930 continue;
5931 }
5932 }
5933 }
5934}
5935
5936extern "C" {
5937
5938void clang_annotateTokens(CXTranslationUnit TU,
5939 CXToken *Tokens, unsigned NumTokens,
5940 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005941 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005942 LOG_BAD_TU(TU);
5943 return;
5944 }
5945 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005946 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005947 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005948 }
5949
5950 LOG_FUNC_SECTION {
5951 *Log << TU << ' ';
5952 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5953 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5954 *Log << clang_getRange(bloc, eloc);
5955 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005956
5957 // Any token we don't specifically annotate will have a NULL cursor.
5958 CXCursor C = clang_getNullCursor();
5959 for (unsigned I = 0; I != NumTokens; ++I)
5960 Cursors[I] = C;
5961
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005962 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 if (!CXXUnit)
5964 return;
5965
5966 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5967
5968 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5969 llvm::CrashRecoveryContext CRC;
5970 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5971 GetSafetyThreadStackSize() * 2)) {
5972 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5973 }
5974}
5975
5976} // end: extern "C"
5977
5978//===----------------------------------------------------------------------===//
5979// Operations for querying linkage of a cursor.
5980//===----------------------------------------------------------------------===//
5981
5982extern "C" {
5983CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5984 if (!clang_isDeclaration(cursor.kind))
5985 return CXLinkage_Invalid;
5986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005987 const Decl *D = cxcursor::getCursorDecl(cursor);
5988 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005989 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005990 case NoLinkage:
5991 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 case InternalLinkage: return CXLinkage_Internal;
5993 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5994 case ExternalLinkage: return CXLinkage_External;
5995 };
5996
5997 return CXLinkage_Invalid;
5998}
5999} // end: extern "C"
6000
6001//===----------------------------------------------------------------------===//
6002// Operations for querying language of a cursor.
6003//===----------------------------------------------------------------------===//
6004
6005static CXLanguageKind getDeclLanguage(const Decl *D) {
6006 if (!D)
6007 return CXLanguage_C;
6008
6009 switch (D->getKind()) {
6010 default:
6011 break;
6012 case Decl::ImplicitParam:
6013 case Decl::ObjCAtDefsField:
6014 case Decl::ObjCCategory:
6015 case Decl::ObjCCategoryImpl:
6016 case Decl::ObjCCompatibleAlias:
6017 case Decl::ObjCImplementation:
6018 case Decl::ObjCInterface:
6019 case Decl::ObjCIvar:
6020 case Decl::ObjCMethod:
6021 case Decl::ObjCProperty:
6022 case Decl::ObjCPropertyImpl:
6023 case Decl::ObjCProtocol:
6024 return CXLanguage_ObjC;
6025 case Decl::CXXConstructor:
6026 case Decl::CXXConversion:
6027 case Decl::CXXDestructor:
6028 case Decl::CXXMethod:
6029 case Decl::CXXRecord:
6030 case Decl::ClassTemplate:
6031 case Decl::ClassTemplatePartialSpecialization:
6032 case Decl::ClassTemplateSpecialization:
6033 case Decl::Friend:
6034 case Decl::FriendTemplate:
6035 case Decl::FunctionTemplate:
6036 case Decl::LinkageSpec:
6037 case Decl::Namespace:
6038 case Decl::NamespaceAlias:
6039 case Decl::NonTypeTemplateParm:
6040 case Decl::StaticAssert:
6041 case Decl::TemplateTemplateParm:
6042 case Decl::TemplateTypeParm:
6043 case Decl::UnresolvedUsingTypename:
6044 case Decl::UnresolvedUsingValue:
6045 case Decl::Using:
6046 case Decl::UsingDirective:
6047 case Decl::UsingShadow:
6048 return CXLanguage_CPlusPlus;
6049 }
6050
6051 return CXLanguage_C;
6052}
6053
6054extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055
6056static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6057 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6058 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006059
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006060 switch (D->getAvailability()) {
6061 case AR_Available:
6062 case AR_NotYetIntroduced:
6063 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006064 return getCursorAvailabilityForDecl(
6065 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066 return CXAvailability_Available;
6067
6068 case AR_Deprecated:
6069 return CXAvailability_Deprecated;
6070
6071 case AR_Unavailable:
6072 return CXAvailability_NotAvailable;
6073 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006074
6075 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006076}
6077
Guy Benyei11169dd2012-12-18 14:30:41 +00006078enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6079 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006080 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6081 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006082
6083 return CXAvailability_Available;
6084}
6085
6086static CXVersion convertVersion(VersionTuple In) {
6087 CXVersion Out = { -1, -1, -1 };
6088 if (In.empty())
6089 return Out;
6090
6091 Out.Major = In.getMajor();
6092
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006093 Optional<unsigned> Minor = In.getMinor();
6094 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 Out.Minor = *Minor;
6096 else
6097 return Out;
6098
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006099 Optional<unsigned> Subminor = In.getSubminor();
6100 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006101 Out.Subminor = *Subminor;
6102
6103 return Out;
6104}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006105
6106static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6107 int *always_deprecated,
6108 CXString *deprecated_message,
6109 int *always_unavailable,
6110 CXString *unavailable_message,
6111 CXPlatformAvailability *availability,
6112 int availability_size) {
6113 bool HadAvailAttr = false;
6114 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006115 for (auto A : D->attrs()) {
6116 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006117 HadAvailAttr = true;
6118 if (always_deprecated)
6119 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006120 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006121 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006122 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006123 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006124 continue;
6125 }
6126
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006127 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006128 HadAvailAttr = true;
6129 if (always_unavailable)
6130 *always_unavailable = 1;
6131 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006132 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006133 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6134 }
6135 continue;
6136 }
6137
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006138 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006139 HadAvailAttr = true;
6140 if (N < availability_size) {
6141 availability[N].Platform
6142 = cxstring::createDup(Avail->getPlatform()->getName());
6143 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6144 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6145 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6146 availability[N].Unavailable = Avail->getUnavailable();
6147 availability[N].Message = cxstring::createDup(Avail->getMessage());
6148 }
6149 ++N;
6150 }
6151 }
6152
6153 if (!HadAvailAttr)
6154 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6155 return getCursorPlatformAvailabilityForDecl(
6156 cast<Decl>(EnumConst->getDeclContext()),
6157 always_deprecated,
6158 deprecated_message,
6159 always_unavailable,
6160 unavailable_message,
6161 availability,
6162 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006163
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006164 return N;
6165}
6166
Guy Benyei11169dd2012-12-18 14:30:41 +00006167int clang_getCursorPlatformAvailability(CXCursor cursor,
6168 int *always_deprecated,
6169 CXString *deprecated_message,
6170 int *always_unavailable,
6171 CXString *unavailable_message,
6172 CXPlatformAvailability *availability,
6173 int availability_size) {
6174 if (always_deprecated)
6175 *always_deprecated = 0;
6176 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006177 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 if (always_unavailable)
6179 *always_unavailable = 0;
6180 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006181 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006182
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 if (!clang_isDeclaration(cursor.kind))
6184 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006185
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006186 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 if (!D)
6188 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006189
6190 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6191 deprecated_message,
6192 always_unavailable,
6193 unavailable_message,
6194 availability,
6195 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006196}
6197
6198void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6199 clang_disposeString(availability->Platform);
6200 clang_disposeString(availability->Message);
6201}
6202
6203CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6204 if (clang_isDeclaration(cursor.kind))
6205 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6206
6207 return CXLanguage_Invalid;
6208}
6209
6210 /// \brief If the given cursor is the "templated" declaration
6211 /// descibing a class or function template, return the class or
6212 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006213static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006215 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006216
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006217 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6219 return FunTmpl;
6220
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006221 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6223 return ClassTmpl;
6224
6225 return D;
6226}
6227
6228CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6229 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006230 if (const Decl *D = getCursorDecl(cursor)) {
6231 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 if (!DC)
6233 return clang_getNullCursor();
6234
6235 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6236 getCursorTU(cursor));
6237 }
6238 }
6239
6240 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006241 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 return MakeCXCursor(D, getCursorTU(cursor));
6243 }
6244
6245 return clang_getNullCursor();
6246}
6247
6248CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6249 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006250 if (const Decl *D = getCursorDecl(cursor)) {
6251 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 if (!DC)
6253 return clang_getNullCursor();
6254
6255 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6256 getCursorTU(cursor));
6257 }
6258 }
6259
6260 // FIXME: Note that we can't easily compute the lexical context of a
6261 // statement or expression, so we return nothing.
6262 return clang_getNullCursor();
6263}
6264
6265CXFile clang_getIncludedFile(CXCursor cursor) {
6266 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006267 return nullptr;
6268
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006269 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006270 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006271}
6272
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006273unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6274 if (C.kind != CXCursor_ObjCPropertyDecl)
6275 return CXObjCPropertyAttr_noattr;
6276
6277 unsigned Result = CXObjCPropertyAttr_noattr;
6278 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6279 ObjCPropertyDecl::PropertyAttributeKind Attr =
6280 PD->getPropertyAttributesAsWritten();
6281
6282#define SET_CXOBJCPROP_ATTR(A) \
6283 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6284 Result |= CXObjCPropertyAttr_##A
6285 SET_CXOBJCPROP_ATTR(readonly);
6286 SET_CXOBJCPROP_ATTR(getter);
6287 SET_CXOBJCPROP_ATTR(assign);
6288 SET_CXOBJCPROP_ATTR(readwrite);
6289 SET_CXOBJCPROP_ATTR(retain);
6290 SET_CXOBJCPROP_ATTR(copy);
6291 SET_CXOBJCPROP_ATTR(nonatomic);
6292 SET_CXOBJCPROP_ATTR(setter);
6293 SET_CXOBJCPROP_ATTR(atomic);
6294 SET_CXOBJCPROP_ATTR(weak);
6295 SET_CXOBJCPROP_ATTR(strong);
6296 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6297#undef SET_CXOBJCPROP_ATTR
6298
6299 return Result;
6300}
6301
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006302unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6303 if (!clang_isDeclaration(C.kind))
6304 return CXObjCDeclQualifier_None;
6305
6306 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6307 const Decl *D = getCursorDecl(C);
6308 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6309 QT = MD->getObjCDeclQualifier();
6310 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6311 QT = PD->getObjCDeclQualifier();
6312 if (QT == Decl::OBJC_TQ_None)
6313 return CXObjCDeclQualifier_None;
6314
6315 unsigned Result = CXObjCDeclQualifier_None;
6316 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6317 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6318 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6319 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6320 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6321 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6322
6323 return Result;
6324}
6325
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006326unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6327 if (!clang_isDeclaration(C.kind))
6328 return 0;
6329
6330 const Decl *D = getCursorDecl(C);
6331 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6332 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6333 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6334 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6335
6336 return 0;
6337}
6338
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006339unsigned clang_Cursor_isVariadic(CXCursor C) {
6340 if (!clang_isDeclaration(C.kind))
6341 return 0;
6342
6343 const Decl *D = getCursorDecl(C);
6344 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6345 return FD->isVariadic();
6346 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6347 return MD->isVariadic();
6348
6349 return 0;
6350}
6351
Guy Benyei11169dd2012-12-18 14:30:41 +00006352CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6353 if (!clang_isDeclaration(C.kind))
6354 return clang_getNullRange();
6355
6356 const Decl *D = getCursorDecl(C);
6357 ASTContext &Context = getCursorContext(C);
6358 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6359 if (!RC)
6360 return clang_getNullRange();
6361
6362 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6363}
6364
6365CXString clang_Cursor_getRawCommentText(CXCursor C) {
6366 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006367 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006368
6369 const Decl *D = getCursorDecl(C);
6370 ASTContext &Context = getCursorContext(C);
6371 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6372 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6373 StringRef();
6374
6375 // Don't duplicate the string because RawText points directly into source
6376 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006377 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006378}
6379
6380CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6381 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006382 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006383
6384 const Decl *D = getCursorDecl(C);
6385 const ASTContext &Context = getCursorContext(C);
6386 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6387
6388 if (RC) {
6389 StringRef BriefText = RC->getBriefText(Context);
6390
6391 // Don't duplicate the string because RawComment ensures that this memory
6392 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006393 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 }
6395
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006396 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006397}
6398
Guy Benyei11169dd2012-12-18 14:30:41 +00006399CXModule clang_Cursor_getModule(CXCursor C) {
6400 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006401 if (const ImportDecl *ImportD =
6402 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 return ImportD->getImportedModule();
6404 }
6405
Craig Topper69186e72014-06-08 08:38:04 +00006406 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006407}
6408
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006409CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6410 if (isNotUsableTU(TU)) {
6411 LOG_BAD_TU(TU);
6412 return nullptr;
6413 }
6414 if (!File)
6415 return nullptr;
6416 FileEntry *FE = static_cast<FileEntry *>(File);
6417
6418 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6419 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6420 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6421
6422 if (Module *Mod = Header.getModule()) {
6423 if (Header.getRole() != ModuleMap::ExcludedHeader)
6424 return Mod;
6425 }
6426 return nullptr;
6427}
6428
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006429CXFile clang_Module_getASTFile(CXModule CXMod) {
6430 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006431 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006432 Module *Mod = static_cast<Module*>(CXMod);
6433 return const_cast<FileEntry *>(Mod->getASTFile());
6434}
6435
Guy Benyei11169dd2012-12-18 14:30:41 +00006436CXModule clang_Module_getParent(CXModule CXMod) {
6437 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006438 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 Module *Mod = static_cast<Module*>(CXMod);
6440 return Mod->Parent;
6441}
6442
6443CXString clang_Module_getName(CXModule CXMod) {
6444 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006445 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006447 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006448}
6449
6450CXString clang_Module_getFullName(CXModule CXMod) {
6451 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006452 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006454 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006455}
6456
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006457int clang_Module_isSystem(CXModule CXMod) {
6458 if (!CXMod)
6459 return 0;
6460 Module *Mod = static_cast<Module*>(CXMod);
6461 return Mod->IsSystem;
6462}
6463
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006464unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6465 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006467 LOG_BAD_TU(TU);
6468 return 0;
6469 }
6470 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 return 0;
6472 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006473 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6474 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6475 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006476}
6477
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006478CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6479 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006481 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006482 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006483 }
6484 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006485 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006486 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006487 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006488
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006489 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6490 if (Index < TopHeaders.size())
6491 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006492
Craig Topper69186e72014-06-08 08:38:04 +00006493 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006494}
6495
6496} // end: extern "C"
6497
6498//===----------------------------------------------------------------------===//
6499// C++ AST instrospection.
6500//===----------------------------------------------------------------------===//
6501
6502extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006503unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6504 if (!clang_isDeclaration(C.kind))
6505 return 0;
6506
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006507 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006508 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006509 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006510 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6511}
6512
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006513unsigned clang_CXXMethod_isConst(CXCursor C) {
6514 if (!clang_isDeclaration(C.kind))
6515 return 0;
6516
6517 const Decl *D = cxcursor::getCursorDecl(C);
6518 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006519 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006520 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6521}
6522
Guy Benyei11169dd2012-12-18 14:30:41 +00006523unsigned clang_CXXMethod_isStatic(CXCursor C) {
6524 if (!clang_isDeclaration(C.kind))
6525 return 0;
6526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006527 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006528 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006529 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 return (Method && Method->isStatic()) ? 1 : 0;
6531}
6532
6533unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6534 if (!clang_isDeclaration(C.kind))
6535 return 0;
6536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006537 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006538 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006539 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 return (Method && Method->isVirtual()) ? 1 : 0;
6541}
6542} // end: extern "C"
6543
6544//===----------------------------------------------------------------------===//
6545// Attribute introspection.
6546//===----------------------------------------------------------------------===//
6547
6548extern "C" {
6549CXType clang_getIBOutletCollectionType(CXCursor C) {
6550 if (C.kind != CXCursor_IBOutletCollectionAttr)
6551 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6552
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006553 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6555
6556 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6557}
6558} // end: extern "C"
6559
6560//===----------------------------------------------------------------------===//
6561// Inspecting memory usage.
6562//===----------------------------------------------------------------------===//
6563
6564typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6565
6566static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6567 enum CXTUResourceUsageKind k,
6568 unsigned long amount) {
6569 CXTUResourceUsageEntry entry = { k, amount };
6570 entries.push_back(entry);
6571}
6572
6573extern "C" {
6574
6575const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6576 const char *str = "";
6577 switch (kind) {
6578 case CXTUResourceUsage_AST:
6579 str = "ASTContext: expressions, declarations, and types";
6580 break;
6581 case CXTUResourceUsage_Identifiers:
6582 str = "ASTContext: identifiers";
6583 break;
6584 case CXTUResourceUsage_Selectors:
6585 str = "ASTContext: selectors";
6586 break;
6587 case CXTUResourceUsage_GlobalCompletionResults:
6588 str = "Code completion: cached global results";
6589 break;
6590 case CXTUResourceUsage_SourceManagerContentCache:
6591 str = "SourceManager: content cache allocator";
6592 break;
6593 case CXTUResourceUsage_AST_SideTables:
6594 str = "ASTContext: side tables";
6595 break;
6596 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6597 str = "SourceManager: malloc'ed memory buffers";
6598 break;
6599 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6600 str = "SourceManager: mmap'ed memory buffers";
6601 break;
6602 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6603 str = "ExternalASTSource: malloc'ed memory buffers";
6604 break;
6605 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6606 str = "ExternalASTSource: mmap'ed memory buffers";
6607 break;
6608 case CXTUResourceUsage_Preprocessor:
6609 str = "Preprocessor: malloc'ed memory";
6610 break;
6611 case CXTUResourceUsage_PreprocessingRecord:
6612 str = "Preprocessor: PreprocessingRecord";
6613 break;
6614 case CXTUResourceUsage_SourceManager_DataStructures:
6615 str = "SourceManager: data structures and tables";
6616 break;
6617 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6618 str = "Preprocessor: header search tables";
6619 break;
6620 }
6621 return str;
6622}
6623
6624CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006625 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006626 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006627 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 return usage;
6629 }
6630
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006631 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006632 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 ASTContext &astContext = astUnit->getASTContext();
6634
6635 // How much memory is used by AST nodes and types?
6636 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6637 (unsigned long) astContext.getASTAllocatedMemory());
6638
6639 // How much memory is used by identifiers?
6640 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6641 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6642
6643 // How much memory is used for selectors?
6644 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6645 (unsigned long) astContext.Selectors.getTotalMemory());
6646
6647 // How much memory is used by ASTContext's side tables?
6648 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6649 (unsigned long) astContext.getSideTableAllocatedMemory());
6650
6651 // How much memory is used for caching global code completion results?
6652 unsigned long completionBytes = 0;
6653 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006654 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 completionBytes = completionAllocator->getTotalMemory();
6656 }
6657 createCXTUResourceUsageEntry(*entries,
6658 CXTUResourceUsage_GlobalCompletionResults,
6659 completionBytes);
6660
6661 // How much memory is being used by SourceManager's content cache?
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_SourceManagerContentCache,
6664 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6665
6666 // How much memory is being used by the MemoryBuffer's in SourceManager?
6667 const SourceManager::MemoryBufferSizes &srcBufs =
6668 astUnit->getSourceManager().getMemoryBufferSizes();
6669
6670 createCXTUResourceUsageEntry(*entries,
6671 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6672 (unsigned long) srcBufs.malloc_bytes);
6673 createCXTUResourceUsageEntry(*entries,
6674 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6675 (unsigned long) srcBufs.mmap_bytes);
6676 createCXTUResourceUsageEntry(*entries,
6677 CXTUResourceUsage_SourceManager_DataStructures,
6678 (unsigned long) astContext.getSourceManager()
6679 .getDataStructureSizes());
6680
6681 // How much memory is being used by the ExternalASTSource?
6682 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6683 const ExternalASTSource::MemoryBufferSizes &sizes =
6684 esrc->getMemoryBufferSizes();
6685
6686 createCXTUResourceUsageEntry(*entries,
6687 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6688 (unsigned long) sizes.malloc_bytes);
6689 createCXTUResourceUsageEntry(*entries,
6690 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6691 (unsigned long) sizes.mmap_bytes);
6692 }
6693
6694 // How much memory is being used by the Preprocessor?
6695 Preprocessor &pp = astUnit->getPreprocessor();
6696 createCXTUResourceUsageEntry(*entries,
6697 CXTUResourceUsage_Preprocessor,
6698 pp.getTotalMemory());
6699
6700 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6701 createCXTUResourceUsageEntry(*entries,
6702 CXTUResourceUsage_PreprocessingRecord,
6703 pRec->getTotalMemory());
6704 }
6705
6706 createCXTUResourceUsageEntry(*entries,
6707 CXTUResourceUsage_Preprocessor_HeaderSearch,
6708 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006709
Guy Benyei11169dd2012-12-18 14:30:41 +00006710 CXTUResourceUsage usage = { (void*) entries.get(),
6711 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006712 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006713 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 return usage;
6715}
6716
6717void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6718 if (usage.data)
6719 delete (MemUsageEntries*) usage.data;
6720}
6721
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006722CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6723 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006724 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006725 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006726
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006727 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006728 LOG_BAD_TU(TU);
6729 return skipped;
6730 }
6731
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006732 if (!file)
6733 return skipped;
6734
6735 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6736 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6737 if (!ppRec)
6738 return skipped;
6739
6740 ASTContext &Ctx = astUnit->getASTContext();
6741 SourceManager &sm = Ctx.getSourceManager();
6742 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6743 FileID wantedFileID = sm.translateFile(fileEntry);
6744
6745 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6746 std::vector<SourceRange> wantedRanges;
6747 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6748 i != ei; ++i) {
6749 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6750 wantedRanges.push_back(*i);
6751 }
6752
6753 skipped->count = wantedRanges.size();
6754 skipped->ranges = new CXSourceRange[skipped->count];
6755 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6756 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6757
6758 return skipped;
6759}
6760
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006761void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6762 if (ranges) {
6763 delete[] ranges->ranges;
6764 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006765 }
6766}
6767
Guy Benyei11169dd2012-12-18 14:30:41 +00006768} // end extern "C"
6769
6770void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6771 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6772 for (unsigned I = 0; I != Usage.numEntries; ++I)
6773 fprintf(stderr, " %s: %lu\n",
6774 clang_getTUResourceUsageName(Usage.entries[I].kind),
6775 Usage.entries[I].amount);
6776
6777 clang_disposeCXTUResourceUsage(Usage);
6778}
6779
6780//===----------------------------------------------------------------------===//
6781// Misc. utility functions.
6782//===----------------------------------------------------------------------===//
6783
6784/// Default to using an 8 MB stack size on "safety" threads.
6785static unsigned SafetyStackThreadSize = 8 << 20;
6786
6787namespace clang {
6788
6789bool RunSafely(llvm::CrashRecoveryContext &CRC,
6790 void (*Fn)(void*), void *UserData,
6791 unsigned Size) {
6792 if (!Size)
6793 Size = GetSafetyThreadStackSize();
6794 if (Size)
6795 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6796 return CRC.RunSafely(Fn, UserData);
6797}
6798
6799unsigned GetSafetyThreadStackSize() {
6800 return SafetyStackThreadSize;
6801}
6802
6803void SetSafetyThreadStackSize(unsigned Value) {
6804 SafetyStackThreadSize = Value;
6805}
6806
6807}
6808
6809void clang::setThreadBackgroundPriority() {
6810 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6811 return;
6812
Alp Toker1a86ad22014-07-06 06:24:00 +00006813#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006814 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6815#endif
6816}
6817
6818void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6819 if (!Unit)
6820 return;
6821
6822 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6823 DEnd = Unit->stored_diag_end();
6824 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006825 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006826 CXString Msg = clang_formatDiagnostic(&Diag,
6827 clang_defaultDiagnosticDisplayOptions());
6828 fprintf(stderr, "%s\n", clang_getCString(Msg));
6829 clang_disposeString(Msg);
6830 }
6831#ifdef LLVM_ON_WIN32
6832 // On Windows, force a flush, since there may be multiple copies of
6833 // stderr and stdout in the file system, all with different buffers
6834 // but writing to the same device.
6835 fflush(stderr);
6836#endif
6837}
6838
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6840 SourceLocation MacroDefLoc,
6841 CXTranslationUnit TU){
6842 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006843 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006844 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006845 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006847 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006848 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006849 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006850 if (MD) {
6851 for (MacroDirective::DefInfo
6852 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6853 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6854 return Def.getMacroInfo();
6855 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006856 }
6857
Craig Topper69186e72014-06-08 08:38:04 +00006858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006859}
6860
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006861const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6862 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006863 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006864 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006865 const IdentifierInfo *II = MacroDef->getName();
6866 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006867 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868
6869 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6870}
6871
6872MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6873 const Token &Tok,
6874 CXTranslationUnit TU) {
6875 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006879
6880 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6883 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006884 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006885
6886 // Check that the token is inside the definition and not its argument list.
6887 SourceManager &SM = Unit->getSourceManager();
6888 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006889 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006890 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892
6893 Preprocessor &PP = Unit->getPreprocessor();
6894 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6895 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006897
Alp Toker2d57cea2014-05-17 04:53:25 +00006898 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006899 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006900 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006901
6902 // Check that the identifier is not one of the macro arguments.
6903 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006905
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006906 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6907 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006908 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006909
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006910 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006911}
6912
6913MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6914 SourceLocation Loc,
6915 CXTranslationUnit TU) {
6916 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006917 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006918
6919 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006920 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006921 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006922 Preprocessor &PP = Unit->getPreprocessor();
6923 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006924 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006925 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6926 Token Tok;
6927 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006929
6930 return checkForMacroInMacroDefinition(MI, Tok, TU);
6931}
6932
Guy Benyei11169dd2012-12-18 14:30:41 +00006933extern "C" {
6934
6935CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006936 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006937}
6938
6939} // end: extern "C"
6940
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006941Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6942 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006943 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006944 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006945 if (Unit->isMainFileAST())
6946 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006947 return *this;
6948 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006949 } else {
6950 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006951 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006952 return *this;
6953}
6954
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006955Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6956 *this << FE->getName();
6957 return *this;
6958}
6959
6960Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6961 CXString cursorName = clang_getCursorDisplayName(cursor);
6962 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6963 clang_disposeString(cursorName);
6964 return *this;
6965}
6966
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006967Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6968 CXFile File;
6969 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006970 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006971 CXString FileName = clang_getFileName(File);
6972 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6973 clang_disposeString(FileName);
6974 return *this;
6975}
6976
6977Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6978 CXSourceLocation BLoc = clang_getRangeStart(range);
6979 CXSourceLocation ELoc = clang_getRangeEnd(range);
6980
6981 CXFile BFile;
6982 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006983 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006984
6985 CXFile EFile;
6986 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006987 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006988
6989 CXString BFileName = clang_getFileName(BFile);
6990 if (BFile == EFile) {
6991 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6992 BLine, BColumn, ELine, EColumn);
6993 } else {
6994 CXString EFileName = clang_getFileName(EFile);
6995 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6996 BLine, BColumn)
6997 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6998 ELine, EColumn);
6999 clang_disposeString(EFileName);
7000 }
7001 clang_disposeString(BFileName);
7002 return *this;
7003}
7004
7005Logger &cxindex::Logger::operator<<(CXString Str) {
7006 *this << clang_getCString(Str);
7007 return *this;
7008}
7009
7010Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7011 LogOS << Fmt;
7012 return *this;
7013}
7014
Chandler Carruth37ad2582014-06-27 15:14:39 +00007015static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7016
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007017cxindex::Logger::~Logger() {
7018 LogOS.flush();
7019
Chandler Carruth37ad2582014-06-27 15:14:39 +00007020 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007021
7022 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7023
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007024 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007025 OS << "[libclang:" << Name << ':';
7026
Alp Toker1a86ad22014-07-06 06:24:00 +00007027#ifdef USE_DARWIN_THREADS
7028 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007029 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7030 OS << tid << ':';
7031#endif
7032
7033 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7034 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7035 OS << Msg.str() << '\n';
7036
7037 if (Trace) {
7038 llvm::sys::PrintStackTrace(stderr);
7039 OS << "--------------------------------------------------\n";
7040 }
7041}