blob: ce74f9f9c416e6e1eb5cfec106ccdc7013c4de11 [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);
Alexander Musman80c22892014-07-17 08:54:58 +00001863 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001864 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001865 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001866 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001867 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001868 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001869 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870
Guy Benyei11169dd2012-12-18 14:30:41 +00001871private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1874 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1876 void AddStmt(const Stmt *S);
1877 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001880 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001881};
1882} // end anonyous namespace
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 // 'S' should always be non-null, since it comes from the
1886 // statement we are visiting.
1887 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1888}
1889
1890void
1891EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1892 if (Qualifier)
1893 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1894}
1895
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 if (S)
1898 WL.push_back(StmtVisit(S, Parent));
1899}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 if (D)
1902 WL.push_back(DeclVisit(D, Parent, isFirst));
1903}
1904void EnqueueVisitor::
1905 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1906 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001908}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001909void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 if (D)
1911 WL.push_back(MemberRefVisit(D, L, Parent));
1912}
1913void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1914 if (TI)
1915 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1916 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001920 AddStmt(*Child);
1921 }
1922 if (size == WL.size())
1923 return;
1924 // Now reverse the entries we just added. This will match the DFS
1925 // ordering performed by the worklist.
1926 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1927 std::reverse(I, E);
1928}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929namespace {
1930class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1931 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001932 /// \brief Process clauses with list of variables.
1933 template <typename T>
1934 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935public:
1936 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1937#define OPENMP_CLAUSE(Name, Class) \
1938 void Visit##Class(const Class *C);
1939#include "clang/Basic/OpenMPKinds.def"
1940};
1941
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001942void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1943 Visitor->AddStmt(C->getCondition());
1944}
1945
Alexey Bataev3778b602014-07-17 07:32:53 +00001946void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1947 Visitor->AddStmt(C->getCondition());
1948}
1949
Alexey Bataev568a8332014-03-06 06:15:19 +00001950void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1951 Visitor->AddStmt(C->getNumThreads());
1952}
1953
Alexey Bataev62c87d22014-03-21 04:51:18 +00001954void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1955 Visitor->AddStmt(C->getSafelen());
1956}
1957
Alexander Musman8bd31e62014-05-27 15:12:19 +00001958void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1959 Visitor->AddStmt(C->getNumForLoops());
1960}
1961
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001963
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001964void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1965
Alexey Bataev56dafe82014-06-20 07:16:17 +00001966void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1967 Visitor->AddStmt(C->getChunkSize());
1968}
1969
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001970void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1971
Alexey Bataev236070f2014-06-20 11:19:47 +00001972void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1973
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001974void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1975
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001976void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1977
Alexey Bataev756c1962013-09-24 03:17:45 +00001978template<typename T>
1979void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001980 for (const auto *I : Node->varlists())
1981 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001982}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001983
1984void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001985 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001986}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001987void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1988 const OMPFirstprivateClause *C) {
1989 VisitOMPClauseList(C);
1990}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001991void OMPClauseEnqueue::VisitOMPLastprivateClause(
1992 const OMPLastprivateClause *C) {
1993 VisitOMPClauseList(C);
1994}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001995void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001996 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001997}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001998void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1999 VisitOMPClauseList(C);
2000}
Alexander Musman8dba6642014-04-22 13:09:42 +00002001void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2002 VisitOMPClauseList(C);
2003 Visitor->AddStmt(C->getStep());
2004}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002005void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2006 VisitOMPClauseList(C);
2007 Visitor->AddStmt(C->getAlignment());
2008}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002009void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2010 VisitOMPClauseList(C);
2011}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002012void
2013OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2014 VisitOMPClauseList(C);
2015}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002016}
Alexey Bataev756c1962013-09-24 03:17:45 +00002017
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002018void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2019 unsigned size = WL.size();
2020 OMPClauseEnqueue Visitor(this);
2021 Visitor.Visit(S);
2022 if (size == WL.size())
2023 return;
2024 // Now reverse the entries we just added. This will match the DFS
2025 // ordering performed by the worklist.
2026 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2027 std::reverse(I, E);
2028}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002029void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002030 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2031}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 AddDecl(B->getBlockDecl());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 EnqueueChildren(E);
2037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2040 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 E = S->body_rend(); I != E; ++I) {
2042 AddStmt(*I);
2043 }
2044}
2045void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 AddStmt(S->getSubStmt());
2048 AddDeclarationNameInfo(S);
2049 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2050 AddNestedNameSpecifierLoc(QualifierLoc);
2051}
2052
2053void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2056 AddDeclarationNameInfo(E);
2057 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2058 AddNestedNameSpecifierLoc(QualifierLoc);
2059 if (!E->isImplicitAccess())
2060 AddStmt(E->getBase());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 // Enqueue the initializer , if any.
2064 AddStmt(E->getInitializer());
2065 // Enqueue the array size, if any.
2066 AddStmt(E->getArraySize());
2067 // Enqueue the allocated type.
2068 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2069 // Enqueue the placement arguments.
2070 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2071 AddStmt(E->getPlacementArg(I-1));
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2075 AddStmt(CE->getArg(I-1));
2076 AddStmt(CE->getCallee());
2077 AddStmt(CE->getArg(0));
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2080 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 // Visit the name of the type being destroyed.
2082 AddTypeLoc(E->getDestroyedTypeInfo());
2083 // Visit the scope type that looks disturbingly like the nested-name-specifier
2084 // but isn't.
2085 AddTypeLoc(E->getScopeTypeInfo());
2086 // Visit the nested-name-specifier.
2087 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2088 AddNestedNameSpecifierLoc(QualifierLoc);
2089 // Visit base expression.
2090 AddStmt(E->getBase());
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2093 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 AddTypeLoc(E->getTypeSourceInfo());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2097 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 EnqueueChildren(E);
2099 AddTypeLoc(E->getTypeSourceInfo());
2100}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002102 EnqueueChildren(E);
2103 if (E->isTypeOperand())
2104 AddTypeLoc(E->getTypeOperandSourceInfo());
2105}
2106
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2108 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 EnqueueChildren(E);
2110 AddTypeLoc(E->getTypeSourceInfo());
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 if (E->isTypeOperand())
2115 AddTypeLoc(E->getTypeOperandSourceInfo());
2116}
2117
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 EnqueueChildren(S);
2120 AddDecl(S->getExceptionDecl());
2121}
2122
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 if (DR->hasExplicitTemplateArgs()) {
2125 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2126 }
2127 WL.push_back(DeclRefExprParts(DR, Parent));
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2130 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2132 AddDeclarationNameInfo(E);
2133 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 unsigned size = WL.size();
2137 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002138 for (const auto *D : S->decls()) {
2139 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 isFirst = false;
2141 }
2142 if (size == WL.size())
2143 return;
2144 // Now reverse the entries we just added. This will match the DFS
2145 // ordering performed by the worklist.
2146 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2147 std::reverse(I, E);
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 D = E->designators_rbegin(), DEnd = E->designators_rend();
2153 D != DEnd; ++D) {
2154 if (D->isFieldDesignator()) {
2155 if (FieldDecl *Field = D->getField())
2156 AddMemberRef(Field, D->getFieldLoc());
2157 continue;
2158 }
2159 if (D->isArrayDesignator()) {
2160 AddStmt(E->getArrayIndex(*D));
2161 continue;
2162 }
2163 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2164 AddStmt(E->getArrayRangeEnd(*D));
2165 AddStmt(E->getArrayRangeStart(*D));
2166 }
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 EnqueueChildren(E);
2170 AddTypeLoc(E->getTypeInfoAsWritten());
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddStmt(FS->getBody());
2174 AddStmt(FS->getInc());
2175 AddStmt(FS->getCond());
2176 AddDecl(FS->getConditionVariable());
2177 AddStmt(FS->getInit());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 AddStmt(If->getElse());
2184 AddStmt(If->getThen());
2185 AddStmt(If->getCond());
2186 AddDecl(If->getConditionVariable());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 // We care about the syntactic form of the initializer list, only.
2190 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2191 IE = Syntactic;
2192 EnqueueChildren(IE);
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 WL.push_back(MemberExprParts(M, Parent));
2196
2197 // If the base of the member access expression is an implicit 'this', don't
2198 // visit it.
2199 // FIXME: If we ever want to show these implicit accesses, this will be
2200 // unfortunate. However, clang_getCursor() relies on this behavior.
2201 if (!M->isImplicitAccess())
2202 AddStmt(M->getBase());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddTypeLoc(E->getEncodedTypeSourceInfo());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 EnqueueChildren(M);
2209 AddTypeLoc(M->getClassReceiverTypeInfo());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 // Visit the components of the offsetof expression.
2213 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2214 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2215 const OffsetOfNode &Node = E->getComponent(I-1);
2216 switch (Node.getKind()) {
2217 case OffsetOfNode::Array:
2218 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2219 break;
2220 case OffsetOfNode::Field:
2221 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2222 break;
2223 case OffsetOfNode::Identifier:
2224 case OffsetOfNode::Base:
2225 continue;
2226 }
2227 }
2228 // Visit the type into which we're computing the offset.
2229 AddTypeLoc(E->getTypeSourceInfo());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2233 WL.push_back(OverloadExprParts(E, Parent));
2234}
2235void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(E);
2238 if (E->isArgumentType())
2239 AddTypeLoc(E->getArgumentTypeInfo());
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 EnqueueChildren(S);
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddStmt(S->getBody());
2246 AddStmt(S->getCond());
2247 AddDecl(S->getConditionVariable());
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddStmt(W->getBody());
2252 AddStmt(W->getCond());
2253 AddDecl(W->getConditionVariable());
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 for (unsigned I = E->getNumArgs(); I > 0; --I)
2258 AddTypeLoc(E->getArg(I-1));
2259}
2260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddTypeLoc(E->getQueriedTypeSourceInfo());
2263}
2264
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(E);
2267}
2268
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 VisitOverloadExpr(U);
2271 if (!U->isImplicitAccess())
2272 AddStmt(U->getBase());
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddStmt(E->getSubExpr());
2276 AddTypeLoc(E->getWrittenTypeInfo());
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 WL.push_back(SizeOfPackExprParts(E, Parent));
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 // If the opaque value has a source expression, just transparently
2283 // visit that. This is useful for (e.g.) pseudo-object expressions.
2284 if (Expr *SourceExpr = E->getSourceExpr())
2285 return Visit(SourceExpr);
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 AddStmt(E->getBody());
2289 WL.push_back(LambdaExprParts(E, Parent));
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 // Treat the expression like its syntactic form.
2293 Visit(E->getSyntacticForm());
2294}
2295
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002296void EnqueueVisitor::VisitOMPExecutableDirective(
2297 const OMPExecutableDirective *D) {
2298 EnqueueChildren(D);
2299 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2300 E = D->clauses().end();
2301 I != E; ++I)
2302 EnqueueChildren(*I);
2303}
2304
2305void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2306 VisitOMPExecutableDirective(D);
2307}
2308
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002309void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2310 VisitOMPExecutableDirective(D);
2311}
2312
Alexey Bataevf29276e2014-06-18 04:14:57 +00002313void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2314 VisitOMPExecutableDirective(D);
2315}
2316
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002317void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2318 VisitOMPExecutableDirective(D);
2319}
2320
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002321void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2322 VisitOMPExecutableDirective(D);
2323}
2324
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002325void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2326 VisitOMPExecutableDirective(D);
2327}
2328
Alexander Musman80c22892014-07-17 08:54:58 +00002329void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2330 VisitOMPExecutableDirective(D);
2331}
2332
Alexey Bataev4acb8592014-07-07 13:01:15 +00002333void
2334EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002338void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2339 const OMPParallelSectionsDirective *D) {
2340 VisitOMPExecutableDirective(D);
2341}
2342
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002343void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2344 VisitOMPExecutableDirective(D);
2345}
2346
Alexey Bataev68446b72014-07-18 07:47:19 +00002347void
2348EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2349 VisitOMPExecutableDirective(D);
2350}
2351
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002352void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2353 VisitOMPExecutableDirective(D);
2354}
2355
Alexey Bataev2df347a2014-07-18 10:17:07 +00002356void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358}
2359
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2362}
2363
2364bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2365 if (RegionOfInterest.isValid()) {
2366 SourceRange Range = getRawCursorExtent(C);
2367 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2368 return false;
2369 }
2370 return true;
2371}
2372
2373bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2374 while (!WL.empty()) {
2375 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002376 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002377
2378 // Set the Parent field, then back to its old value once we're done.
2379 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2380
2381 switch (LI.getKind()) {
2382 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 if (!D)
2385 continue;
2386
2387 // For now, perform default visitation for Decls.
2388 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2389 cast<DeclVisit>(&LI)->isFirst())))
2390 return true;
2391
2392 continue;
2393 }
2394 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2395 const ASTTemplateArgumentListInfo *ArgList =
2396 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2397 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2398 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2399 Arg != ArgEnd; ++Arg) {
2400 if (VisitTemplateArgumentLoc(*Arg))
2401 return true;
2402 }
2403 continue;
2404 }
2405 case VisitorJob::TypeLocVisitKind: {
2406 // Perform default visitation for TypeLocs.
2407 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2408 return true;
2409 continue;
2410 }
2411 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 if (LabelStmt *stmt = LS->getStmt()) {
2414 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2415 TU))) {
2416 return true;
2417 }
2418 }
2419 continue;
2420 }
2421
2422 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2423 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2424 if (VisitNestedNameSpecifierLoc(V->get()))
2425 return true;
2426 continue;
2427 }
2428
2429 case VisitorJob::DeclarationNameInfoVisitKind: {
2430 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2431 ->get()))
2432 return true;
2433 continue;
2434 }
2435 case VisitorJob::MemberRefVisitKind: {
2436 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2437 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2438 return true;
2439 continue;
2440 }
2441 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 if (!S)
2444 continue;
2445
2446 // Update the current cursor.
2447 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2448 if (!IsInRegionOfInterest(Cursor))
2449 continue;
2450 switch (Visitor(Cursor, Parent, ClientData)) {
2451 case CXChildVisit_Break: return true;
2452 case CXChildVisit_Continue: break;
2453 case CXChildVisit_Recurse:
2454 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002455 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 EnqueueWorkList(WL, S);
2457 break;
2458 }
2459 continue;
2460 }
2461 case VisitorJob::MemberExprPartsKind: {
2462 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002464
2465 // Visit the nested-name-specifier
2466 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2467 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2468 return true;
2469
2470 // Visit the declaration name.
2471 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2472 return true;
2473
2474 // Visit the explicitly-specified template arguments, if any.
2475 if (M->hasExplicitTemplateArgs()) {
2476 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2477 *ArgEnd = Arg + M->getNumTemplateArgs();
2478 Arg != ArgEnd; ++Arg) {
2479 if (VisitTemplateArgumentLoc(*Arg))
2480 return true;
2481 }
2482 }
2483 continue;
2484 }
2485 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002486 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 // Visit nested-name-specifier, if present.
2488 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2489 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2490 return true;
2491 // Visit declaration name.
2492 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2493 return true;
2494 continue;
2495 }
2496 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 // Visit the nested-name-specifier.
2499 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2500 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2501 return true;
2502 // Visit the declaration name.
2503 if (VisitDeclarationNameInfo(O->getNameInfo()))
2504 return true;
2505 // Visit the overloaded declaration reference.
2506 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2507 return true;
2508 continue;
2509 }
2510 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002511 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 NamedDecl *Pack = E->getPack();
2513 if (isa<TemplateTypeParmDecl>(Pack)) {
2514 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2515 E->getPackLoc(), TU)))
2516 return true;
2517
2518 continue;
2519 }
2520
2521 if (isa<TemplateTemplateParmDecl>(Pack)) {
2522 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2523 E->getPackLoc(), TU)))
2524 return true;
2525
2526 continue;
2527 }
2528
2529 // Non-type template parameter packs and function parameter packs are
2530 // treated like DeclRefExpr cursors.
2531 continue;
2532 }
2533
2534 case VisitorJob::LambdaExprPartsKind: {
2535 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002536 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2538 CEnd = E->explicit_capture_end();
2539 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002540 // FIXME: Lambda init-captures.
2541 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002542 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002543
Guy Benyei11169dd2012-12-18 14:30:41 +00002544 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2545 C->getLocation(),
2546 TU)))
2547 return true;
2548 }
2549
2550 // Visit parameters and return type, if present.
2551 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2552 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2553 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2554 // Visit the whole type.
2555 if (Visit(TL))
2556 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002557 } else if (FunctionProtoTypeLoc Proto =
2558 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 if (E->hasExplicitParameters()) {
2560 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002561 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2562 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002563 return true;
2564 } else {
2565 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002566 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 return true;
2568 }
2569 }
2570 }
2571 break;
2572 }
2573
2574 case VisitorJob::PostChildrenVisitKind:
2575 if (PostChildrenVisitor(Parent, ClientData))
2576 return true;
2577 break;
2578 }
2579 }
2580 return false;
2581}
2582
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002583bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002584 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002585 if (!WorkListFreeList.empty()) {
2586 WL = WorkListFreeList.back();
2587 WL->clear();
2588 WorkListFreeList.pop_back();
2589 }
2590 else {
2591 WL = new VisitorWorkList();
2592 WorkListCache.push_back(WL);
2593 }
2594 EnqueueWorkList(*WL, S);
2595 bool result = RunVisitorWorkList(*WL);
2596 WorkListFreeList.push_back(WL);
2597 return result;
2598}
2599
2600namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002601typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002602RefNamePieces
2603buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2604 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2605 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002606 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2607 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2608 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2609
2610 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2611
2612 RefNamePieces Pieces;
2613
2614 if (WantQualifier && QLoc.isValid())
2615 Pieces.push_back(QLoc);
2616
2617 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2618 Pieces.push_back(NI.getLoc());
2619
2620 if (WantTemplateArgs && TemplateArgs)
2621 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2622 TemplateArgs->RAngleLoc));
2623
2624 if (Kind == DeclarationName::CXXOperatorName) {
2625 Pieces.push_back(SourceLocation::getFromRawEncoding(
2626 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2627 Pieces.push_back(SourceLocation::getFromRawEncoding(
2628 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2629 }
2630
2631 if (WantSinglePiece) {
2632 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2633 Pieces.clear();
2634 Pieces.push_back(R);
2635 }
2636
2637 return Pieces;
2638}
2639}
2640
2641//===----------------------------------------------------------------------===//
2642// Misc. API hooks.
2643//===----------------------------------------------------------------------===//
2644
Chad Rosier05c71aa2013-03-27 18:28:23 +00002645static void fatal_error_handler(void *user_data, const std::string& reason,
2646 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002647 // Write the result out to stderr avoiding errs() because raw_ostreams can
2648 // call report_fatal_error.
2649 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2650 ::abort();
2651}
2652
Chandler Carruth66660742014-06-27 16:37:27 +00002653namespace {
2654struct RegisterFatalErrorHandler {
2655 RegisterFatalErrorHandler() {
2656 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2657 }
2658};
2659}
2660
2661static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2662
Guy Benyei11169dd2012-12-18 14:30:41 +00002663extern "C" {
2664CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2665 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002666 // We use crash recovery to make some of our APIs more reliable, implicitly
2667 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002668 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2669 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002670
Chandler Carruth66660742014-06-27 16:37:27 +00002671 // Look through the managed static to trigger construction of the managed
2672 // static which registers our fatal error handler. This ensures it is only
2673 // registered once.
2674 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002675
2676 CIndexer *CIdxr = new CIndexer();
2677 if (excludeDeclarationsFromPCH)
2678 CIdxr->setOnlyLocalDecls();
2679 if (displayDiagnostics)
2680 CIdxr->setDisplayDiagnostics();
2681
2682 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2683 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2684 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2685 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2686 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2687 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2688
2689 return CIdxr;
2690}
2691
2692void clang_disposeIndex(CXIndex CIdx) {
2693 if (CIdx)
2694 delete static_cast<CIndexer *>(CIdx);
2695}
2696
2697void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2698 if (CIdx)
2699 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2700}
2701
2702unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2703 if (CIdx)
2704 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2705 return 0;
2706}
2707
2708void clang_toggleCrashRecovery(unsigned isEnabled) {
2709 if (isEnabled)
2710 llvm::CrashRecoveryContext::Enable();
2711 else
2712 llvm::CrashRecoveryContext::Disable();
2713}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002714
Guy Benyei11169dd2012-12-18 14:30:41 +00002715CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2716 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002717 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002718 enum CXErrorCode Result =
2719 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002720 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002721 assert((TU && Result == CXError_Success) ||
2722 (!TU && Result != CXError_Success));
2723 return TU;
2724}
2725
2726enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2727 const char *ast_filename,
2728 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002729 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002730 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002731
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002732 if (!CIdx || !ast_filename || !out_TU)
2733 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002734
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002735 LOG_FUNC_SECTION {
2736 *Log << ast_filename;
2737 }
2738
Guy Benyei11169dd2012-12-18 14:30:41 +00002739 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2740 FileSystemOptions FileSystemOpts;
2741
2742 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002743 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002744 CXXIdx->getOnlyLocalDecls(), None,
2745 /*CaptureDiagnostics=*/true,
2746 /*AllowPCHWithCompilerErrors=*/true,
2747 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002748 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2749 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002750}
2751
2752unsigned clang_defaultEditingTranslationUnitOptions() {
2753 return CXTranslationUnit_PrecompiledPreamble |
2754 CXTranslationUnit_CacheCompletionResults;
2755}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002756
Guy Benyei11169dd2012-12-18 14:30:41 +00002757CXTranslationUnit
2758clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2759 const char *source_filename,
2760 int num_command_line_args,
2761 const char * const *command_line_args,
2762 unsigned num_unsaved_files,
2763 struct CXUnsavedFile *unsaved_files) {
2764 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2765 return clang_parseTranslationUnit(CIdx, source_filename,
2766 command_line_args, num_command_line_args,
2767 unsaved_files, num_unsaved_files,
2768 Options);
2769}
2770
2771struct ParseTranslationUnitInfo {
2772 CXIndex CIdx;
2773 const char *source_filename;
2774 const char *const *command_line_args;
2775 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002776 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002778 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002779 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002780};
2781static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002782 const ParseTranslationUnitInfo *PTUI =
2783 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 CXIndex CIdx = PTUI->CIdx;
2785 const char *source_filename = PTUI->source_filename;
2786 const char * const *command_line_args = PTUI->command_line_args;
2787 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002789 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002790
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002791 // Set up the initial return values.
2792 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002793 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002794
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002795 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002796 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002797 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 }
2800
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2802
2803 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2804 setThreadBackgroundPriority();
2805
2806 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2807 // FIXME: Add a flag for modules.
2808 TranslationUnitKind TUKind
2809 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002810 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002811 = options & CXTranslationUnit_CacheCompletionResults;
2812 bool IncludeBriefCommentsInCodeCompletion
2813 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2814 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2815 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2816
2817 // Configure the diagnostics.
2818 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002819 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002820
2821 // Recover resources if we crash before exiting this function.
2822 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2823 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002824 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002825
Ahmed Charlesb8984322014-03-07 20:03:18 +00002826 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2827 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002828
2829 // Recover resources if we crash before exiting this function.
2830 llvm::CrashRecoveryContextCleanupRegistrar<
2831 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2832
Alp Toker9d85b182014-07-07 01:23:14 +00002833 for (auto &UF : PTUI->unsaved_files) {
2834 llvm::MemoryBuffer *MB =
2835 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2836 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 }
2838
Ahmed Charlesb8984322014-03-07 20:03:18 +00002839 std::unique_ptr<std::vector<const char *>> Args(
2840 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002841
2842 // Recover resources if we crash before exiting this method.
2843 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2844 ArgsCleanup(Args.get());
2845
2846 // Since the Clang C library is primarily used by batch tools dealing with
2847 // (often very broken) source code, where spell-checking can have a
2848 // significant negative impact on performance (particularly when
2849 // precompiled headers are involved), we disable it by default.
2850 // Only do this if we haven't found a spell-checking-related argument.
2851 bool FoundSpellCheckingArgument = false;
2852 for (int I = 0; I != num_command_line_args; ++I) {
2853 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2854 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2855 FoundSpellCheckingArgument = true;
2856 break;
2857 }
2858 }
2859 if (!FoundSpellCheckingArgument)
2860 Args->push_back("-fno-spell-checking");
2861
2862 Args->insert(Args->end(), command_line_args,
2863 command_line_args + num_command_line_args);
2864
2865 // The 'source_filename' argument is optional. If the caller does not
2866 // specify it then it is assumed that the source file is specified
2867 // in the actual argument list.
2868 // Put the source file after command_line_args otherwise if '-x' flag is
2869 // present it will be unused.
2870 if (source_filename)
2871 Args->push_back(source_filename);
2872
2873 // Do we need the detailed preprocessing record?
2874 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2875 Args->push_back("-Xclang");
2876 Args->push_back("-detailed-preprocessing-record");
2877 }
2878
2879 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002880 std::unique_ptr<ASTUnit> ErrUnit;
2881 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002882 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002883 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2884 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2885 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2886 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2887 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2888 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002889
2890 if (NumErrors != Diags->getClient()->getNumErrors()) {
2891 // Make sure to check that 'Unit' is non-NULL.
2892 if (CXXIdx->getDisplayDiagnostics())
2893 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2894 }
2895
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002896 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2897 PTUI->result = CXError_ASTReadError;
2898 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002899 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002900 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2901 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002902}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002903
2904CXTranslationUnit
2905clang_parseTranslationUnit(CXIndex CIdx,
2906 const char *source_filename,
2907 const char *const *command_line_args,
2908 int num_command_line_args,
2909 struct CXUnsavedFile *unsaved_files,
2910 unsigned num_unsaved_files,
2911 unsigned options) {
2912 CXTranslationUnit TU;
2913 enum CXErrorCode Result = clang_parseTranslationUnit2(
2914 CIdx, source_filename, command_line_args, num_command_line_args,
2915 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002916 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002917 assert((TU && Result == CXError_Success) ||
2918 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002919 return TU;
2920}
2921
2922enum CXErrorCode clang_parseTranslationUnit2(
2923 CXIndex CIdx,
2924 const char *source_filename,
2925 const char *const *command_line_args,
2926 int num_command_line_args,
2927 struct CXUnsavedFile *unsaved_files,
2928 unsigned num_unsaved_files,
2929 unsigned options,
2930 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002931 LOG_FUNC_SECTION {
2932 *Log << source_filename << ": ";
2933 for (int i = 0; i != num_command_line_args; ++i)
2934 *Log << command_line_args[i] << " ";
2935 }
2936
Alp Toker9d85b182014-07-07 01:23:14 +00002937 if (num_unsaved_files && !unsaved_files)
2938 return CXError_InvalidArguments;
2939
Alp Toker5c532982014-07-07 22:42:03 +00002940 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002941 ParseTranslationUnitInfo PTUI = {
2942 CIdx,
2943 source_filename,
2944 command_line_args,
2945 num_command_line_args,
2946 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2947 options,
2948 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002949 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 llvm::CrashRecoveryContext CRC;
2951
2952 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2953 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2954 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2955 fprintf(stderr, " 'command_line_args' : [");
2956 for (int i = 0; i != num_command_line_args; ++i) {
2957 if (i)
2958 fprintf(stderr, ", ");
2959 fprintf(stderr, "'%s'", command_line_args[i]);
2960 }
2961 fprintf(stderr, "],\n");
2962 fprintf(stderr, " 'unsaved_files' : [");
2963 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2964 if (i)
2965 fprintf(stderr, ", ");
2966 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2967 unsaved_files[i].Length);
2968 }
2969 fprintf(stderr, "],\n");
2970 fprintf(stderr, " 'options' : %d,\n", options);
2971 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002972
2973 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002974 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 if (CXTranslationUnit *TU = PTUI.out_TU)
2976 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 }
Alp Toker5c532982014-07-07 22:42:03 +00002978
2979 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002980}
2981
2982unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2983 return CXSaveTranslationUnit_None;
2984}
2985
2986namespace {
2987
2988struct SaveTranslationUnitInfo {
2989 CXTranslationUnit TU;
2990 const char *FileName;
2991 unsigned options;
2992 CXSaveError result;
2993};
2994
2995}
2996
2997static void clang_saveTranslationUnit_Impl(void *UserData) {
2998 SaveTranslationUnitInfo *STUI =
2999 static_cast<SaveTranslationUnitInfo*>(UserData);
3000
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003001 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3003 setThreadBackgroundPriority();
3004
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003005 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3007}
3008
3009int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3010 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003011 LOG_FUNC_SECTION {
3012 *Log << TU << ' ' << FileName;
3013 }
3014
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003015 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003016 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003018 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003019
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003020 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3022 if (!CXXUnit->hasSema())
3023 return CXSaveError_InvalidTU;
3024
3025 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3026
3027 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3028 getenv("LIBCLANG_NOTHREADS")) {
3029 clang_saveTranslationUnit_Impl(&STUI);
3030
3031 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3032 PrintLibclangResourceUsage(TU);
3033
3034 return STUI.result;
3035 }
3036
3037 // We have an AST that has invalid nodes due to compiler errors.
3038 // Use a crash recovery thread for protection.
3039
3040 llvm::CrashRecoveryContext CRC;
3041
3042 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3043 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3044 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3045 fprintf(stderr, " 'options' : %d,\n", options);
3046 fprintf(stderr, "}\n");
3047
3048 return CXSaveError_Unknown;
3049
3050 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3051 PrintLibclangResourceUsage(TU);
3052 }
3053
3054 return STUI.result;
3055}
3056
3057void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3058 if (CTUnit) {
3059 // If the translation unit has been marked as unsafe to free, just discard
3060 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3062 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003063 return;
3064
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003065 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003066 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3068 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003069 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 delete CTUnit;
3071 }
3072}
3073
3074unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3075 return CXReparse_None;
3076}
3077
3078struct ReparseTranslationUnitInfo {
3079 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003080 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003082 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003083};
3084
3085static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003086 const ReparseTranslationUnitInfo *RTUI =
3087 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003088 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003089 unsigned options = RTUI->options;
3090 (void) options;
3091
3092 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003093 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003094 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003095 RTUI->result = CXError_InvalidArguments;
3096 return;
3097 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
3099 // Reset the associated diagnostics.
3100 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003101 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003102
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003103 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3105 setThreadBackgroundPriority();
3106
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003107 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003109
3110 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3111 new std::vector<ASTUnit::RemappedFile>());
3112
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 // Recover resources if we crash before exiting this function.
3114 llvm::CrashRecoveryContextCleanupRegistrar<
3115 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003116
3117 for (auto &UF : RTUI->unsaved_files) {
3118 llvm::MemoryBuffer *MB =
3119 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3120 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003122
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003123 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003124 RTUI->result = CXError_Success;
3125 else if (isASTReadError(CXXUnit))
3126 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003127}
3128
3129int clang_reparseTranslationUnit(CXTranslationUnit TU,
3130 unsigned num_unsaved_files,
3131 struct CXUnsavedFile *unsaved_files,
3132 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003133 LOG_FUNC_SECTION {
3134 *Log << TU;
3135 }
3136
Alp Toker9d85b182014-07-07 01:23:14 +00003137 if (num_unsaved_files && !unsaved_files)
3138 return CXError_InvalidArguments;
3139
Alp Toker5c532982014-07-07 22:42:03 +00003140 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003141 ReparseTranslationUnitInfo RTUI = {
3142 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003143 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003144
3145 if (getenv("LIBCLANG_NOTHREADS")) {
3146 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003147 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 }
3149
3150 llvm::CrashRecoveryContext CRC;
3151
3152 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3153 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003154 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003155 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3157 PrintLibclangResourceUsage(TU);
3158
Alp Toker5c532982014-07-07 22:42:03 +00003159 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003160}
3161
3162
3163CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003164 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003165 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003166 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003167 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003168
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003169 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003170 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003171}
3172
3173CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003174 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003175 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003176 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003177 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003178
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003179 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3181}
3182
3183} // end: extern "C"
3184
3185//===----------------------------------------------------------------------===//
3186// CXFile Operations.
3187//===----------------------------------------------------------------------===//
3188
3189extern "C" {
3190CXString clang_getFileName(CXFile SFile) {
3191 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003192 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003193
3194 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003195 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003196}
3197
3198time_t clang_getFileTime(CXFile SFile) {
3199 if (!SFile)
3200 return 0;
3201
3202 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3203 return FEnt->getModificationTime();
3204}
3205
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003206CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003207 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003208 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003209 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003210 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003211
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003212 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003213
3214 FileManager &FMgr = CXXUnit->getFileManager();
3215 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3216}
3217
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003218unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3219 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003220 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003221 LOG_BAD_TU(TU);
3222 return 0;
3223 }
3224
3225 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003226 return 0;
3227
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003228 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 FileEntry *FEnt = static_cast<FileEntry *>(file);
3230 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3231 .isFileMultipleIncludeGuarded(FEnt);
3232}
3233
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003234int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3235 if (!file || !outID)
3236 return 1;
3237
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003238 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003239 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3240 outID->data[0] = ID.getDevice();
3241 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003242 outID->data[2] = FEnt->getModificationTime();
3243 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003244}
3245
Guy Benyei11169dd2012-12-18 14:30:41 +00003246} // end: extern "C"
3247
3248//===----------------------------------------------------------------------===//
3249// CXCursor Operations.
3250//===----------------------------------------------------------------------===//
3251
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003252static const Decl *getDeclFromExpr(const Stmt *E) {
3253 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return getDeclFromExpr(CE->getSubExpr());
3255
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003256 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003258 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003260 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003262 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 if (PRE->isExplicitProperty())
3264 return PRE->getExplicitProperty();
3265 // It could be messaging both getter and setter as in:
3266 // ++myobj.myprop;
3267 // in which case prefer to associate the setter since it is less obvious
3268 // from inspecting the source that the setter is going to get called.
3269 if (PRE->isMessagingSetter())
3270 return PRE->getImplicitPropertySetter();
3271 return PRE->getImplicitPropertyGetter();
3272 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003273 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (Expr *Src = OVE->getSourceExpr())
3277 return getDeclFromExpr(Src);
3278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 if (!CE->isElidable())
3283 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 return OME->getMethodDecl();
3286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3291 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3294 isa<ParmVarDecl>(SizeOfPack->getPack()))
3295 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003296
3297 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003298}
3299
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003300static SourceLocation getLocationFromExpr(const Expr *E) {
3301 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 return getLocationFromExpr(CE->getSubExpr());
3303
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003304 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003306 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003308 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003310 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003312 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003314 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 return PropRef->getLocation();
3316
3317 return E->getLocStart();
3318}
3319
3320extern "C" {
3321
3322unsigned clang_visitChildren(CXCursor parent,
3323 CXCursorVisitor visitor,
3324 CXClientData client_data) {
3325 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3326 /*VisitPreprocessorLast=*/false);
3327 return CursorVis.VisitChildren(parent);
3328}
3329
3330#ifndef __has_feature
3331#define __has_feature(x) 0
3332#endif
3333#if __has_feature(blocks)
3334typedef enum CXChildVisitResult
3335 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3336
3337static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3338 CXClientData client_data) {
3339 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3340 return block(cursor, parent);
3341}
3342#else
3343// If we are compiled with a compiler that doesn't have native blocks support,
3344// define and call the block manually, so the
3345typedef struct _CXChildVisitResult
3346{
3347 void *isa;
3348 int flags;
3349 int reserved;
3350 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3351 CXCursor);
3352} *CXCursorVisitorBlock;
3353
3354static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3355 CXClientData client_data) {
3356 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3357 return block->invoke(block, cursor, parent);
3358}
3359#endif
3360
3361
3362unsigned clang_visitChildrenWithBlock(CXCursor parent,
3363 CXCursorVisitorBlock block) {
3364 return clang_visitChildren(parent, visitWithBlock, block);
3365}
3366
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003370
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003371 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const ObjCPropertyImplDecl *PropImpl =
3374 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003382 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 }
3384
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003385 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003388 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3390 // and returns different names. NamedDecl returns the class name and
3391 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003392 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393
3394 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003395 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003396
3397 SmallString<1024> S;
3398 llvm::raw_svector_ostream os(S);
3399 ND->printName(os);
3400
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003401 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003402}
3403
3404CXString clang_getCursorSpelling(CXCursor C) {
3405 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003406 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003407
3408 if (clang_isReference(C.kind)) {
3409 switch (C.kind) {
3410 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003411 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003412 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003415 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003416 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003419 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003421 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 }
3423 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003424 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003425 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 }
3427 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003428 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 assert(Type && "Missing type decl");
3430
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003431 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 getAsString());
3433 }
3434 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003435 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 assert(Template && "Missing template decl");
3437
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003438 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 }
3440
3441 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003442 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 assert(NS && "Missing namespace decl");
3444
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003445 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 }
3447
3448 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003449 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 assert(Field && "Missing member decl");
3451
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003452 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454
3455 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003456 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 assert(Label && "Missing label");
3458
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003459 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 }
3461
3462 case CXCursor_OverloadedDeclRef: {
3463 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3465 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003466 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003467 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003469 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003470 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 OverloadedTemplateStorage *Ovl
3472 = Storage.get<OverloadedTemplateStorage*>();
3473 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003474 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003475 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 }
3477
3478 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003479 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 assert(Var && "Missing variable decl");
3481
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003482 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 }
3484
3485 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003486 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 }
3488 }
3489
3490 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003491 const Expr *E = getCursorExpr(C);
3492
3493 if (C.kind == CXCursor_ObjCStringLiteral ||
3494 C.kind == CXCursor_StringLiteral) {
3495 const StringLiteral *SLit;
3496 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3497 SLit = OSL->getString();
3498 } else {
3499 SLit = cast<StringLiteral>(E);
3500 }
3501 SmallString<256> Buf;
3502 llvm::raw_svector_ostream OS(Buf);
3503 SLit->outputString(OS);
3504 return cxstring::createDup(OS.str());
3505 }
3506
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 if (D)
3509 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003510 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 }
3512
3513 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003514 const Stmt *S = getCursorStmt(C);
3515 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003516 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003518 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003522 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 ->getNameStart());
3524
3525 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 ->getNameStart());
3528
3529 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003530 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531
3532 if (clang_isDeclaration(C.kind))
3533 return getDeclSpelling(getCursorDecl(C));
3534
3535 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003536 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 }
3539
3540 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003541 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003542 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
3544
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003545 if (C.kind == CXCursor_PackedAttr) {
3546 return cxstring::createRef("packed");
3547 }
3548
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003549 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003550}
3551
3552CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3553 unsigned pieceIndex,
3554 unsigned options) {
3555 if (clang_Cursor_isNull(C))
3556 return clang_getNullRange();
3557
3558 ASTContext &Ctx = getCursorContext(C);
3559
3560 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003561 const Stmt *S = getCursorStmt(C);
3562 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 if (pieceIndex > 0)
3564 return clang_getNullRange();
3565 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3566 }
3567
3568 return clang_getNullRange();
3569 }
3570
3571 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003572 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3574 if (pieceIndex >= ME->getNumSelectorLocs())
3575 return clang_getNullRange();
3576 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3577 }
3578 }
3579
3580 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3581 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003582 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3584 if (pieceIndex >= MD->getNumSelectorLocs())
3585 return clang_getNullRange();
3586 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3587 }
3588 }
3589
3590 if (C.kind == CXCursor_ObjCCategoryDecl ||
3591 C.kind == CXCursor_ObjCCategoryImplDecl) {
3592 if (pieceIndex > 0)
3593 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003594 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3596 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3599 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3600 }
3601
3602 if (C.kind == CXCursor_ModuleImportDecl) {
3603 if (pieceIndex > 0)
3604 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003605 if (const ImportDecl *ImportD =
3606 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3608 if (!Locs.empty())
3609 return cxloc::translateSourceRange(Ctx,
3610 SourceRange(Locs.front(), Locs.back()));
3611 }
3612 return clang_getNullRange();
3613 }
3614
3615 // FIXME: A CXCursor_InclusionDirective should give the location of the
3616 // filename, but we don't keep track of this.
3617
3618 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3619 // but we don't keep track of this.
3620
3621 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3622 // but we don't keep track of this.
3623
3624 // Default handling, give the location of the cursor.
3625
3626 if (pieceIndex > 0)
3627 return clang_getNullRange();
3628
3629 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3630 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3631 return cxloc::translateSourceRange(Ctx, Loc);
3632}
3633
3634CXString clang_getCursorDisplayName(CXCursor C) {
3635 if (!clang_isDeclaration(C.kind))
3636 return clang_getCursorSpelling(C);
3637
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003638 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003640 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003641
3642 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003643 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 D = FunTmpl->getTemplatedDecl();
3645
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003646 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 SmallString<64> Str;
3648 llvm::raw_svector_ostream OS(Str);
3649 OS << *Function;
3650 if (Function->getPrimaryTemplate())
3651 OS << "<>";
3652 OS << "(";
3653 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3654 if (I)
3655 OS << ", ";
3656 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3657 }
3658
3659 if (Function->isVariadic()) {
3660 if (Function->getNumParams())
3661 OS << ", ";
3662 OS << "...";
3663 }
3664 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003665 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 }
3667
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003668 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 SmallString<64> Str;
3670 llvm::raw_svector_ostream OS(Str);
3671 OS << *ClassTemplate;
3672 OS << "<";
3673 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3674 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3675 if (I)
3676 OS << ", ";
3677
3678 NamedDecl *Param = Params->getParam(I);
3679 if (Param->getIdentifier()) {
3680 OS << Param->getIdentifier()->getName();
3681 continue;
3682 }
3683
3684 // There is no parameter name, which makes this tricky. Try to come up
3685 // with something useful that isn't too long.
3686 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3687 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3688 else if (NonTypeTemplateParmDecl *NTTP
3689 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3690 OS << NTTP->getType().getAsString(Policy);
3691 else
3692 OS << "template<...> class";
3693 }
3694
3695 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003696 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 }
3698
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003699 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3701 // If the type was explicitly written, use that.
3702 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003703 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003704
Benjamin Kramer9170e912013-02-22 15:46:01 +00003705 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 llvm::raw_svector_ostream OS(Str);
3707 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003708 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 ClassSpec->getTemplateArgs().data(),
3710 ClassSpec->getTemplateArgs().size(),
3711 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003712 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 }
3714
3715 return clang_getCursorSpelling(C);
3716}
3717
3718CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3719 switch (Kind) {
3720 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003848 case CXCursor_ObjCSelfExpr:
3849 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003938 case CXCursor_SEHLeaveStmt:
3939 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003968 case CXCursor_PackedAttr:
3969 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003970 case CXCursor_PureAttr:
3971 return cxstring::createRef("attribute(pure)");
3972 case CXCursor_ConstAttr:
3973 return cxstring::createRef("attribute(const)");
3974 case CXCursor_NoDuplicateAttr:
3975 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003976 case CXCursor_CUDAConstantAttr:
3977 return cxstring::createRef("attribute(constant)");
3978 case CXCursor_CUDADeviceAttr:
3979 return cxstring::createRef("attribute(device)");
3980 case CXCursor_CUDAGlobalAttr:
3981 return cxstring::createRef("attribute(global)");
3982 case CXCursor_CUDAHostAttr:
3983 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004032 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004033 return cxstring::createRef("OMPParallelDirective");
4034 case CXCursor_OMPSimdDirective:
4035 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004036 case CXCursor_OMPForDirective:
4037 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004038 case CXCursor_OMPSectionsDirective:
4039 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004040 case CXCursor_OMPSectionDirective:
4041 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004042 case CXCursor_OMPSingleDirective:
4043 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004044 case CXCursor_OMPMasterDirective:
4045 return cxstring::createRef("OMPMasterDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004046 case CXCursor_OMPParallelForDirective:
4047 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004048 case CXCursor_OMPParallelSectionsDirective:
4049 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004050 case CXCursor_OMPTaskDirective:
4051 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004052 case CXCursor_OMPTaskyieldDirective:
4053 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004054 case CXCursor_OMPBarrierDirective:
4055 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004056 case CXCursor_OMPTaskwaitDirective:
4057 return cxstring::createRef("OMPTaskwaitDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 }
4059
4060 llvm_unreachable("Unhandled CXCursorKind");
4061}
4062
4063struct GetCursorData {
4064 SourceLocation TokenBeginLoc;
4065 bool PointsAtMacroArgExpansion;
4066 bool VisitedObjCPropertyImplDecl;
4067 SourceLocation VisitedDeclaratorDeclStartLoc;
4068 CXCursor &BestCursor;
4069
4070 GetCursorData(SourceManager &SM,
4071 SourceLocation tokenBegin, CXCursor &outputCursor)
4072 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4073 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4074 VisitedObjCPropertyImplDecl = false;
4075 }
4076};
4077
4078static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4079 CXCursor parent,
4080 CXClientData client_data) {
4081 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4082 CXCursor *BestCursor = &Data->BestCursor;
4083
4084 // If we point inside a macro argument we should provide info of what the
4085 // token is so use the actual cursor, don't replace it with a macro expansion
4086 // cursor.
4087 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4088 return CXChildVisit_Recurse;
4089
4090 if (clang_isDeclaration(cursor.kind)) {
4091 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004092 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4094 if (MD->isImplicit())
4095 return CXChildVisit_Break;
4096
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004097 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4099 // Check that when we have multiple @class references in the same line,
4100 // that later ones do not override the previous ones.
4101 // If we have:
4102 // @class Foo, Bar;
4103 // source ranges for both start at '@', so 'Bar' will end up overriding
4104 // 'Foo' even though the cursor location was at 'Foo'.
4105 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4106 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004107 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4109 if (PrevID != ID &&
4110 !PrevID->isThisDeclarationADefinition() &&
4111 !ID->isThisDeclarationADefinition())
4112 return CXChildVisit_Break;
4113 }
4114
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004115 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4117 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4118 // Check that when we have multiple declarators in the same line,
4119 // that later ones do not override the previous ones.
4120 // If we have:
4121 // int Foo, Bar;
4122 // source ranges for both start at 'int', so 'Bar' will end up overriding
4123 // 'Foo' even though the cursor location was at 'Foo'.
4124 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4125 return CXChildVisit_Break;
4126 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4127
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004128 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4130 (void)PropImp;
4131 // Check that when we have multiple @synthesize in the same line,
4132 // that later ones do not override the previous ones.
4133 // If we have:
4134 // @synthesize Foo, Bar;
4135 // source ranges for both start at '@', so 'Bar' will end up overriding
4136 // 'Foo' even though the cursor location was at 'Foo'.
4137 if (Data->VisitedObjCPropertyImplDecl)
4138 return CXChildVisit_Break;
4139 Data->VisitedObjCPropertyImplDecl = true;
4140 }
4141 }
4142
4143 if (clang_isExpression(cursor.kind) &&
4144 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004145 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 // Avoid having the cursor of an expression replace the declaration cursor
4147 // when the expression source range overlaps the declaration range.
4148 // This can happen for C++ constructor expressions whose range generally
4149 // include the variable declaration, e.g.:
4150 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4151 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4152 D->getLocation() == Data->TokenBeginLoc)
4153 return CXChildVisit_Break;
4154 }
4155 }
4156
4157 // If our current best cursor is the construction of a temporary object,
4158 // don't replace that cursor with a type reference, because we want
4159 // clang_getCursor() to point at the constructor.
4160 if (clang_isExpression(BestCursor->kind) &&
4161 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4162 cursor.kind == CXCursor_TypeRef) {
4163 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4164 // as having the actual point on the type reference.
4165 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4166 return CXChildVisit_Recurse;
4167 }
4168
4169 *BestCursor = cursor;
4170 return CXChildVisit_Recurse;
4171}
4172
4173CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004174 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004175 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004177 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004178
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004179 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4181
4182 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4183 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4184
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004185 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 CXFile SearchFile;
4187 unsigned SearchLine, SearchColumn;
4188 CXFile ResultFile;
4189 unsigned ResultLine, ResultColumn;
4190 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4191 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4192 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004193
4194 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4195 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004196 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004197 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 SearchFileName = clang_getFileName(SearchFile);
4199 ResultFileName = clang_getFileName(ResultFile);
4200 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4201 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004202 *Log << llvm::format("(%s:%d:%d) = %s",
4203 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4204 clang_getCString(KindSpelling))
4205 << llvm::format("(%s:%d:%d):%s%s",
4206 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4207 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 clang_disposeString(SearchFileName);
4209 clang_disposeString(ResultFileName);
4210 clang_disposeString(KindSpelling);
4211 clang_disposeString(USR);
4212
4213 CXCursor Definition = clang_getCursorDefinition(Result);
4214 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4215 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4216 CXString DefinitionKindSpelling
4217 = clang_getCursorKindSpelling(Definition.kind);
4218 CXFile DefinitionFile;
4219 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004220 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004221 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004223 *Log << llvm::format(" -> %s(%s:%d:%d)",
4224 clang_getCString(DefinitionKindSpelling),
4225 clang_getCString(DefinitionFileName),
4226 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 clang_disposeString(DefinitionFileName);
4228 clang_disposeString(DefinitionKindSpelling);
4229 }
4230 }
4231
4232 return Result;
4233}
4234
4235CXCursor clang_getNullCursor(void) {
4236 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4237}
4238
4239unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004240 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4241 // can't set consistently. For example, when visiting a DeclStmt we will set
4242 // it but we don't set it on the result of clang_getCursorDefinition for
4243 // a reference of the same declaration.
4244 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4245 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4246 // to provide that kind of info.
4247 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004248 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004249 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004250 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004251
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 return X == Y;
4253}
4254
4255unsigned clang_hashCursor(CXCursor C) {
4256 unsigned Index = 0;
4257 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4258 Index = 1;
4259
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004260 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 std::make_pair(C.kind, C.data[Index]));
4262}
4263
4264unsigned clang_isInvalid(enum CXCursorKind K) {
4265 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4266}
4267
4268unsigned clang_isDeclaration(enum CXCursorKind K) {
4269 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4270 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4271}
4272
4273unsigned clang_isReference(enum CXCursorKind K) {
4274 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4275}
4276
4277unsigned clang_isExpression(enum CXCursorKind K) {
4278 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4279}
4280
4281unsigned clang_isStatement(enum CXCursorKind K) {
4282 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4283}
4284
4285unsigned clang_isAttribute(enum CXCursorKind K) {
4286 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4287}
4288
4289unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4290 return K == CXCursor_TranslationUnit;
4291}
4292
4293unsigned clang_isPreprocessing(enum CXCursorKind K) {
4294 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4295}
4296
4297unsigned clang_isUnexposed(enum CXCursorKind K) {
4298 switch (K) {
4299 case CXCursor_UnexposedDecl:
4300 case CXCursor_UnexposedExpr:
4301 case CXCursor_UnexposedStmt:
4302 case CXCursor_UnexposedAttr:
4303 return true;
4304 default:
4305 return false;
4306 }
4307}
4308
4309CXCursorKind clang_getCursorKind(CXCursor C) {
4310 return C.kind;
4311}
4312
4313CXSourceLocation clang_getCursorLocation(CXCursor C) {
4314 if (clang_isReference(C.kind)) {
4315 switch (C.kind) {
4316 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004317 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 = getCursorObjCSuperClassRef(C);
4319 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4320 }
4321
4322 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004323 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 = getCursorObjCProtocolRef(C);
4325 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4326 }
4327
4328 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004329 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 = getCursorObjCClassRef(C);
4331 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4332 }
4333
4334 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004335 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4337 }
4338
4339 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004340 std::pair<const TemplateDecl *, SourceLocation> P =
4341 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4343 }
4344
4345 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004346 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4348 }
4349
4350 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004351 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4353 }
4354
4355 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004356 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4358 }
4359
4360 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004361 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 if (!BaseSpec)
4363 return clang_getNullLocation();
4364
4365 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4366 return cxloc::translateSourceLocation(getCursorContext(C),
4367 TSInfo->getTypeLoc().getBeginLoc());
4368
4369 return cxloc::translateSourceLocation(getCursorContext(C),
4370 BaseSpec->getLocStart());
4371 }
4372
4373 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004374 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4376 }
4377
4378 case CXCursor_OverloadedDeclRef:
4379 return cxloc::translateSourceLocation(getCursorContext(C),
4380 getCursorOverloadedDeclRef(C).second);
4381
4382 default:
4383 // FIXME: Need a way to enumerate all non-reference cases.
4384 llvm_unreachable("Missed a reference kind");
4385 }
4386 }
4387
4388 if (clang_isExpression(C.kind))
4389 return cxloc::translateSourceLocation(getCursorContext(C),
4390 getLocationFromExpr(getCursorExpr(C)));
4391
4392 if (clang_isStatement(C.kind))
4393 return cxloc::translateSourceLocation(getCursorContext(C),
4394 getCursorStmt(C)->getLocStart());
4395
4396 if (C.kind == CXCursor_PreprocessingDirective) {
4397 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4398 return cxloc::translateSourceLocation(getCursorContext(C), L);
4399 }
4400
4401 if (C.kind == CXCursor_MacroExpansion) {
4402 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004403 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 return cxloc::translateSourceLocation(getCursorContext(C), L);
4405 }
4406
4407 if (C.kind == CXCursor_MacroDefinition) {
4408 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4409 return cxloc::translateSourceLocation(getCursorContext(C), L);
4410 }
4411
4412 if (C.kind == CXCursor_InclusionDirective) {
4413 SourceLocation L
4414 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4415 return cxloc::translateSourceLocation(getCursorContext(C), L);
4416 }
4417
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004418 if (clang_isAttribute(C.kind)) {
4419 SourceLocation L
4420 = cxcursor::getCursorAttr(C)->getLocation();
4421 return cxloc::translateSourceLocation(getCursorContext(C), L);
4422 }
4423
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (!clang_isDeclaration(C.kind))
4425 return clang_getNullLocation();
4426
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004427 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 if (!D)
4429 return clang_getNullLocation();
4430
4431 SourceLocation Loc = D->getLocation();
4432 // FIXME: Multiple variables declared in a single declaration
4433 // currently lack the information needed to correctly determine their
4434 // ranges when accounting for the type-specifier. We use context
4435 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4436 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 if (!cxcursor::isFirstInDeclGroup(C))
4439 Loc = VD->getLocation();
4440 }
4441
4442 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004443 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 Loc = MD->getSelectorStartLoc();
4445
4446 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4447}
4448
4449} // end extern "C"
4450
4451CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4452 assert(TU);
4453
4454 // Guard against an invalid SourceLocation, or we may assert in one
4455 // of the following calls.
4456 if (SLoc.isInvalid())
4457 return clang_getNullCursor();
4458
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004459 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004460
4461 // Translate the given source location to make it point at the beginning of
4462 // the token under the cursor.
4463 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4464 CXXUnit->getASTContext().getLangOpts());
4465
4466 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4467 if (SLoc.isValid()) {
4468 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4469 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4470 /*VisitPreprocessorLast=*/true,
4471 /*VisitIncludedEntities=*/false,
4472 SourceLocation(SLoc));
4473 CursorVis.visitFileRegion();
4474 }
4475
4476 return Result;
4477}
4478
4479static SourceRange getRawCursorExtent(CXCursor C) {
4480 if (clang_isReference(C.kind)) {
4481 switch (C.kind) {
4482 case CXCursor_ObjCSuperClassRef:
4483 return getCursorObjCSuperClassRef(C).second;
4484
4485 case CXCursor_ObjCProtocolRef:
4486 return getCursorObjCProtocolRef(C).second;
4487
4488 case CXCursor_ObjCClassRef:
4489 return getCursorObjCClassRef(C).second;
4490
4491 case CXCursor_TypeRef:
4492 return getCursorTypeRef(C).second;
4493
4494 case CXCursor_TemplateRef:
4495 return getCursorTemplateRef(C).second;
4496
4497 case CXCursor_NamespaceRef:
4498 return getCursorNamespaceRef(C).second;
4499
4500 case CXCursor_MemberRef:
4501 return getCursorMemberRef(C).second;
4502
4503 case CXCursor_CXXBaseSpecifier:
4504 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4505
4506 case CXCursor_LabelRef:
4507 return getCursorLabelRef(C).second;
4508
4509 case CXCursor_OverloadedDeclRef:
4510 return getCursorOverloadedDeclRef(C).second;
4511
4512 case CXCursor_VariableRef:
4513 return getCursorVariableRef(C).second;
4514
4515 default:
4516 // FIXME: Need a way to enumerate all non-reference cases.
4517 llvm_unreachable("Missed a reference kind");
4518 }
4519 }
4520
4521 if (clang_isExpression(C.kind))
4522 return getCursorExpr(C)->getSourceRange();
4523
4524 if (clang_isStatement(C.kind))
4525 return getCursorStmt(C)->getSourceRange();
4526
4527 if (clang_isAttribute(C.kind))
4528 return getCursorAttr(C)->getRange();
4529
4530 if (C.kind == CXCursor_PreprocessingDirective)
4531 return cxcursor::getCursorPreprocessingDirective(C);
4532
4533 if (C.kind == CXCursor_MacroExpansion) {
4534 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004535 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 return TU->mapRangeFromPreamble(Range);
4537 }
4538
4539 if (C.kind == CXCursor_MacroDefinition) {
4540 ASTUnit *TU = getCursorASTUnit(C);
4541 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4542 return TU->mapRangeFromPreamble(Range);
4543 }
4544
4545 if (C.kind == CXCursor_InclusionDirective) {
4546 ASTUnit *TU = getCursorASTUnit(C);
4547 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4548 return TU->mapRangeFromPreamble(Range);
4549 }
4550
4551 if (C.kind == CXCursor_TranslationUnit) {
4552 ASTUnit *TU = getCursorASTUnit(C);
4553 FileID MainID = TU->getSourceManager().getMainFileID();
4554 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4555 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4556 return SourceRange(Start, End);
4557 }
4558
4559 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004560 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 if (!D)
4562 return SourceRange();
4563
4564 SourceRange R = D->getSourceRange();
4565 // FIXME: Multiple variables declared in a single declaration
4566 // currently lack the information needed to correctly determine their
4567 // ranges when accounting for the type-specifier. We use context
4568 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4569 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004570 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 if (!cxcursor::isFirstInDeclGroup(C))
4572 R.setBegin(VD->getLocation());
4573 }
4574 return R;
4575 }
4576 return SourceRange();
4577}
4578
4579/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4580/// the decl-specifier-seq for declarations.
4581static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4582 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004583 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 if (!D)
4585 return SourceRange();
4586
4587 SourceRange R = D->getSourceRange();
4588
4589 // Adjust the start of the location for declarations preceded by
4590 // declaration specifiers.
4591 SourceLocation StartLoc;
4592 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4593 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4594 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004595 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4597 StartLoc = TI->getTypeLoc().getLocStart();
4598 }
4599
4600 if (StartLoc.isValid() && R.getBegin().isValid() &&
4601 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4602 R.setBegin(StartLoc);
4603
4604 // FIXME: Multiple variables declared in a single declaration
4605 // currently lack the information needed to correctly determine their
4606 // ranges when accounting for the type-specifier. We use context
4607 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4608 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004609 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 if (!cxcursor::isFirstInDeclGroup(C))
4611 R.setBegin(VD->getLocation());
4612 }
4613
4614 return R;
4615 }
4616
4617 return getRawCursorExtent(C);
4618}
4619
4620extern "C" {
4621
4622CXSourceRange clang_getCursorExtent(CXCursor C) {
4623 SourceRange R = getRawCursorExtent(C);
4624 if (R.isInvalid())
4625 return clang_getNullRange();
4626
4627 return cxloc::translateSourceRange(getCursorContext(C), R);
4628}
4629
4630CXCursor clang_getCursorReferenced(CXCursor C) {
4631 if (clang_isInvalid(C.kind))
4632 return clang_getNullCursor();
4633
4634 CXTranslationUnit tu = getCursorTU(C);
4635 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004636 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 if (!D)
4638 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004639 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004641 if (const ObjCPropertyImplDecl *PropImpl =
4642 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4644 return MakeCXCursor(Property, tu);
4645
4646 return C;
4647 }
4648
4649 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004650 const Expr *E = getCursorExpr(C);
4651 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 if (D) {
4653 CXCursor declCursor = MakeCXCursor(D, tu);
4654 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4655 declCursor);
4656 return declCursor;
4657 }
4658
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004659 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 return MakeCursorOverloadedDeclRef(Ovl, tu);
4661
4662 return clang_getNullCursor();
4663 }
4664
4665 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004666 const Stmt *S = getCursorStmt(C);
4667 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 if (LabelDecl *label = Goto->getLabel())
4669 if (LabelStmt *labelS = label->getStmt())
4670 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4671
4672 return clang_getNullCursor();
4673 }
4674
4675 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004676 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 return MakeMacroDefinitionCursor(Def, tu);
4678 }
4679
4680 if (!clang_isReference(C.kind))
4681 return clang_getNullCursor();
4682
4683 switch (C.kind) {
4684 case CXCursor_ObjCSuperClassRef:
4685 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4686
4687 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004688 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4689 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return MakeCXCursor(Def, tu);
4691
4692 return MakeCXCursor(Prot, tu);
4693 }
4694
4695 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004696 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4697 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 return MakeCXCursor(Def, tu);
4699
4700 return MakeCXCursor(Class, tu);
4701 }
4702
4703 case CXCursor_TypeRef:
4704 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4705
4706 case CXCursor_TemplateRef:
4707 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4708
4709 case CXCursor_NamespaceRef:
4710 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4711
4712 case CXCursor_MemberRef:
4713 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4714
4715 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004716 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4718 tu ));
4719 }
4720
4721 case CXCursor_LabelRef:
4722 // FIXME: We end up faking the "parent" declaration here because we
4723 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004724 return MakeCXCursor(getCursorLabelRef(C).first,
4725 cxtu::getASTUnit(tu)->getASTContext()
4726 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 tu);
4728
4729 case CXCursor_OverloadedDeclRef:
4730 return C;
4731
4732 case CXCursor_VariableRef:
4733 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4734
4735 default:
4736 // We would prefer to enumerate all non-reference cursor kinds here.
4737 llvm_unreachable("Unhandled reference cursor kind");
4738 }
4739}
4740
4741CXCursor clang_getCursorDefinition(CXCursor C) {
4742 if (clang_isInvalid(C.kind))
4743 return clang_getNullCursor();
4744
4745 CXTranslationUnit TU = getCursorTU(C);
4746
4747 bool WasReference = false;
4748 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4749 C = clang_getCursorReferenced(C);
4750 WasReference = true;
4751 }
4752
4753 if (C.kind == CXCursor_MacroExpansion)
4754 return clang_getCursorReferenced(C);
4755
4756 if (!clang_isDeclaration(C.kind))
4757 return clang_getNullCursor();
4758
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004759 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 if (!D)
4761 return clang_getNullCursor();
4762
4763 switch (D->getKind()) {
4764 // Declaration kinds that don't really separate the notions of
4765 // declaration and definition.
4766 case Decl::Namespace:
4767 case Decl::Typedef:
4768 case Decl::TypeAlias:
4769 case Decl::TypeAliasTemplate:
4770 case Decl::TemplateTypeParm:
4771 case Decl::EnumConstant:
4772 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004773 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 case Decl::IndirectField:
4775 case Decl::ObjCIvar:
4776 case Decl::ObjCAtDefsField:
4777 case Decl::ImplicitParam:
4778 case Decl::ParmVar:
4779 case Decl::NonTypeTemplateParm:
4780 case Decl::TemplateTemplateParm:
4781 case Decl::ObjCCategoryImpl:
4782 case Decl::ObjCImplementation:
4783 case Decl::AccessSpec:
4784 case Decl::LinkageSpec:
4785 case Decl::ObjCPropertyImpl:
4786 case Decl::FileScopeAsm:
4787 case Decl::StaticAssert:
4788 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004789 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 case Decl::Label: // FIXME: Is this right??
4791 case Decl::ClassScopeFunctionSpecialization:
4792 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004793 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return C;
4795
4796 // Declaration kinds that don't make any sense here, but are
4797 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004798 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case Decl::TranslationUnit:
4800 break;
4801
4802 // Declaration kinds for which the definition is not resolvable.
4803 case Decl::UnresolvedUsingTypename:
4804 case Decl::UnresolvedUsingValue:
4805 break;
4806
4807 case Decl::UsingDirective:
4808 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4809 TU);
4810
4811 case Decl::NamespaceAlias:
4812 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4813
4814 case Decl::Enum:
4815 case Decl::Record:
4816 case Decl::CXXRecord:
4817 case Decl::ClassTemplateSpecialization:
4818 case Decl::ClassTemplatePartialSpecialization:
4819 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4820 return MakeCXCursor(Def, TU);
4821 return clang_getNullCursor();
4822
4823 case Decl::Function:
4824 case Decl::CXXMethod:
4825 case Decl::CXXConstructor:
4826 case Decl::CXXDestructor:
4827 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004828 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004830 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 return clang_getNullCursor();
4832 }
4833
Larisse Voufo39a1e502013-08-06 01:03:05 +00004834 case Decl::Var:
4835 case Decl::VarTemplateSpecialization:
4836 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004838 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 return MakeCXCursor(Def, TU);
4840 return clang_getNullCursor();
4841 }
4842
4843 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004844 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4846 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4847 return clang_getNullCursor();
4848 }
4849
4850 case Decl::ClassTemplate: {
4851 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4852 ->getDefinition())
4853 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4854 TU);
4855 return clang_getNullCursor();
4856 }
4857
Larisse Voufo39a1e502013-08-06 01:03:05 +00004858 case Decl::VarTemplate: {
4859 if (VarDecl *Def =
4860 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4861 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4862 return clang_getNullCursor();
4863 }
4864
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 case Decl::Using:
4866 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4867 D->getLocation(), TU);
4868
4869 case Decl::UsingShadow:
4870 return clang_getCursorDefinition(
4871 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4872 TU));
4873
4874 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 if (Method->isThisDeclarationADefinition())
4877 return C;
4878
4879 // Dig out the method definition in the associated
4880 // @implementation, if we have it.
4881 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4884 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4885 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4886 Method->isInstanceMethod()))
4887 if (Def->isThisDeclarationADefinition())
4888 return MakeCXCursor(Def, TU);
4889
4890 return clang_getNullCursor();
4891 }
4892
4893 case Decl::ObjCCategory:
4894 if (ObjCCategoryImplDecl *Impl
4895 = cast<ObjCCategoryDecl>(D)->getImplementation())
4896 return MakeCXCursor(Impl, TU);
4897 return clang_getNullCursor();
4898
4899 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004900 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 return MakeCXCursor(Def, TU);
4902 return clang_getNullCursor();
4903
4904 case Decl::ObjCInterface: {
4905 // There are two notions of a "definition" for an Objective-C
4906 // class: the interface and its implementation. When we resolved a
4907 // reference to an Objective-C class, produce the @interface as
4908 // the definition; when we were provided with the interface,
4909 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 return MakeCXCursor(Def, TU);
4914 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4915 return MakeCXCursor(Impl, TU);
4916 return clang_getNullCursor();
4917 }
4918
4919 case Decl::ObjCProperty:
4920 // FIXME: We don't really know where to find the
4921 // ObjCPropertyImplDecls that implement this property.
4922 return clang_getNullCursor();
4923
4924 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004925 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004927 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 return MakeCXCursor(Def, TU);
4929
4930 return clang_getNullCursor();
4931
4932 case Decl::Friend:
4933 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4934 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4935 return clang_getNullCursor();
4936
4937 case Decl::FriendTemplate:
4938 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4939 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4940 return clang_getNullCursor();
4941 }
4942
4943 return clang_getNullCursor();
4944}
4945
4946unsigned clang_isCursorDefinition(CXCursor C) {
4947 if (!clang_isDeclaration(C.kind))
4948 return 0;
4949
4950 return clang_getCursorDefinition(C) == C;
4951}
4952
4953CXCursor clang_getCanonicalCursor(CXCursor C) {
4954 if (!clang_isDeclaration(C.kind))
4955 return C;
4956
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004957 if (const Decl *D = getCursorDecl(C)) {
4958 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4960 return MakeCXCursor(CatD, getCursorTU(C));
4961
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004962 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4963 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 return MakeCXCursor(IFD, getCursorTU(C));
4965
4966 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4967 }
4968
4969 return C;
4970}
4971
4972int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4973 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4974}
4975
4976unsigned clang_getNumOverloadedDecls(CXCursor C) {
4977 if (C.kind != CXCursor_OverloadedDeclRef)
4978 return 0;
4979
4980 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004981 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 return E->getNumDecls();
4983
4984 if (OverloadedTemplateStorage *S
4985 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4986 return S->size();
4987
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004988 const Decl *D = Storage.get<const Decl *>();
4989 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 return Using->shadow_size();
4991
4992 return 0;
4993}
4994
4995CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4996 if (cursor.kind != CXCursor_OverloadedDeclRef)
4997 return clang_getNullCursor();
4998
4999 if (index >= clang_getNumOverloadedDecls(cursor))
5000 return clang_getNullCursor();
5001
5002 CXTranslationUnit TU = getCursorTU(cursor);
5003 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 return MakeCXCursor(E->decls_begin()[index], TU);
5006
5007 if (OverloadedTemplateStorage *S
5008 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5009 return MakeCXCursor(S->begin()[index], TU);
5010
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005011 const Decl *D = Storage.get<const Decl *>();
5012 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 // FIXME: This is, unfortunately, linear time.
5014 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5015 std::advance(Pos, index);
5016 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5017 }
5018
5019 return clang_getNullCursor();
5020}
5021
5022void clang_getDefinitionSpellingAndExtent(CXCursor C,
5023 const char **startBuf,
5024 const char **endBuf,
5025 unsigned *startLine,
5026 unsigned *startColumn,
5027 unsigned *endLine,
5028 unsigned *endColumn) {
5029 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005030 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005031 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5032
5033 SourceManager &SM = FD->getASTContext().getSourceManager();
5034 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5035 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5036 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5037 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5038 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5039 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5040}
5041
5042
5043CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5044 unsigned PieceIndex) {
5045 RefNamePieces Pieces;
5046
5047 switch (C.kind) {
5048 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005049 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5051 E->getQualifierLoc().getSourceRange());
5052 break;
5053
5054 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005055 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5057 E->getQualifierLoc().getSourceRange(),
5058 E->getOptionalExplicitTemplateArgs());
5059 break;
5060
5061 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005062 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005064 const Expr *Callee = OCE->getCallee();
5065 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 Callee = ICE->getSubExpr();
5067
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005068 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5070 DRE->getQualifierLoc().getSourceRange());
5071 }
5072 break;
5073
5074 default:
5075 break;
5076 }
5077
5078 if (Pieces.empty()) {
5079 if (PieceIndex == 0)
5080 return clang_getCursorExtent(C);
5081 } else if (PieceIndex < Pieces.size()) {
5082 SourceRange R = Pieces[PieceIndex];
5083 if (R.isValid())
5084 return cxloc::translateSourceRange(getCursorContext(C), R);
5085 }
5086
5087 return clang_getNullRange();
5088}
5089
5090void clang_enableStackTraces(void) {
5091 llvm::sys::PrintStackTraceOnErrorSignal();
5092}
5093
5094void clang_executeOnThread(void (*fn)(void*), void *user_data,
5095 unsigned stack_size) {
5096 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5097}
5098
5099} // end: extern "C"
5100
5101//===----------------------------------------------------------------------===//
5102// Token-based Operations.
5103//===----------------------------------------------------------------------===//
5104
5105/* CXToken layout:
5106 * int_data[0]: a CXTokenKind
5107 * int_data[1]: starting token location
5108 * int_data[2]: token length
5109 * int_data[3]: reserved
5110 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5111 * otherwise unused.
5112 */
5113extern "C" {
5114
5115CXTokenKind clang_getTokenKind(CXToken CXTok) {
5116 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5117}
5118
5119CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5120 switch (clang_getTokenKind(CXTok)) {
5121 case CXToken_Identifier:
5122 case CXToken_Keyword:
5123 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005124 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 ->getNameStart());
5126
5127 case CXToken_Literal: {
5128 // We have stashed the starting pointer in the ptr_data field. Use it.
5129 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005130 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 }
5132
5133 case CXToken_Punctuation:
5134 case CXToken_Comment:
5135 break;
5136 }
5137
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005138 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005139 LOG_BAD_TU(TU);
5140 return cxstring::createEmpty();
5141 }
5142
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 // We have to find the starting buffer pointer the hard way, by
5144 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005145 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005147 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005148
5149 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5150 std::pair<FileID, unsigned> LocInfo
5151 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5152 bool Invalid = false;
5153 StringRef Buffer
5154 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5155 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005156 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005157
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005158 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005159}
5160
5161CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005162 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005163 LOG_BAD_TU(TU);
5164 return clang_getNullLocation();
5165 }
5166
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005167 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 if (!CXXUnit)
5169 return clang_getNullLocation();
5170
5171 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5172 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5173}
5174
5175CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005176 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005177 LOG_BAD_TU(TU);
5178 return clang_getNullRange();
5179 }
5180
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005181 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 if (!CXXUnit)
5183 return clang_getNullRange();
5184
5185 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5186 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5187}
5188
5189static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5190 SmallVectorImpl<CXToken> &CXTokens) {
5191 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5192 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005193 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005195 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005196
5197 // Cannot tokenize across files.
5198 if (BeginLocInfo.first != EndLocInfo.first)
5199 return;
5200
5201 // Create a lexer
5202 bool Invalid = false;
5203 StringRef Buffer
5204 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5205 if (Invalid)
5206 return;
5207
5208 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5209 CXXUnit->getASTContext().getLangOpts(),
5210 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5211 Lex.SetCommentRetentionState(true);
5212
5213 // Lex tokens until we hit the end of the range.
5214 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5215 Token Tok;
5216 bool previousWasAt = false;
5217 do {
5218 // Lex the next token
5219 Lex.LexFromRawLexer(Tok);
5220 if (Tok.is(tok::eof))
5221 break;
5222
5223 // Initialize the CXToken.
5224 CXToken CXTok;
5225
5226 // - Common fields
5227 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5228 CXTok.int_data[2] = Tok.getLength();
5229 CXTok.int_data[3] = 0;
5230
5231 // - Kind-specific fields
5232 if (Tok.isLiteral()) {
5233 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005234 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 } else if (Tok.is(tok::raw_identifier)) {
5236 // Lookup the identifier to determine whether we have a keyword.
5237 IdentifierInfo *II
5238 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5239
5240 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5241 CXTok.int_data[0] = CXToken_Keyword;
5242 }
5243 else {
5244 CXTok.int_data[0] = Tok.is(tok::identifier)
5245 ? CXToken_Identifier
5246 : CXToken_Keyword;
5247 }
5248 CXTok.ptr_data = II;
5249 } else if (Tok.is(tok::comment)) {
5250 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005251 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 } else {
5253 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005254 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 }
5256 CXTokens.push_back(CXTok);
5257 previousWasAt = Tok.is(tok::at);
5258 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5259}
5260
5261void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5262 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005263 LOG_FUNC_SECTION {
5264 *Log << TU << ' ' << Range;
5265 }
5266
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005268 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 if (NumTokens)
5270 *NumTokens = 0;
5271
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005272 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005273 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005274 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005275 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005276
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005277 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 if (!CXXUnit || !Tokens || !NumTokens)
5279 return;
5280
5281 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5282
5283 SourceRange R = cxloc::translateCXSourceRange(Range);
5284 if (R.isInvalid())
5285 return;
5286
5287 SmallVector<CXToken, 32> CXTokens;
5288 getTokens(CXXUnit, R, CXTokens);
5289
5290 if (CXTokens.empty())
5291 return;
5292
5293 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5294 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5295 *NumTokens = CXTokens.size();
5296}
5297
5298void clang_disposeTokens(CXTranslationUnit TU,
5299 CXToken *Tokens, unsigned NumTokens) {
5300 free(Tokens);
5301}
5302
5303} // end: extern "C"
5304
5305//===----------------------------------------------------------------------===//
5306// Token annotation APIs.
5307//===----------------------------------------------------------------------===//
5308
Guy Benyei11169dd2012-12-18 14:30:41 +00005309static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5310 CXCursor parent,
5311 CXClientData client_data);
5312static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5313 CXClientData client_data);
5314
5315namespace {
5316class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 CXToken *Tokens;
5318 CXCursor *Cursors;
5319 unsigned NumTokens;
5320 unsigned TokIdx;
5321 unsigned PreprocessingTokIdx;
5322 CursorVisitor AnnotateVis;
5323 SourceManager &SrcMgr;
5324 bool HasContextSensitiveKeywords;
5325
5326 struct PostChildrenInfo {
5327 CXCursor Cursor;
5328 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005329 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 unsigned BeforeChildrenTokenIdx;
5331 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005332 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005333
5334 CXToken &getTok(unsigned Idx) {
5335 assert(Idx < NumTokens);
5336 return Tokens[Idx];
5337 }
5338 const CXToken &getTok(unsigned Idx) const {
5339 assert(Idx < NumTokens);
5340 return Tokens[Idx];
5341 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 bool MoreTokens() const { return TokIdx < NumTokens; }
5343 unsigned NextToken() const { return TokIdx; }
5344 void AdvanceToken() { ++TokIdx; }
5345 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005346 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 }
5348 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005349 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 }
5351 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005352 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 }
5354
5355 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005356 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 SourceRange);
5358
5359public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005360 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005361 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005362 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005364 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 AnnotateTokensVisitor, this,
5366 /*VisitPreprocessorLast=*/true,
5367 /*VisitIncludedEntities=*/false,
5368 RegionOfInterest,
5369 /*VisitDeclsOnly=*/false,
5370 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005371 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 HasContextSensitiveKeywords(false) { }
5373
5374 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5375 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5376 bool postVisitChildren(CXCursor cursor);
5377 void AnnotateTokens();
5378
5379 /// \brief Determine whether the annotator saw any cursors that have
5380 /// context-sensitive keywords.
5381 bool hasContextSensitiveKeywords() const {
5382 return HasContextSensitiveKeywords;
5383 }
5384
5385 ~AnnotateTokensWorker() {
5386 assert(PostChildrenInfos.empty());
5387 }
5388};
5389}
5390
5391void AnnotateTokensWorker::AnnotateTokens() {
5392 // Walk the AST within the region of interest, annotating tokens
5393 // along the way.
5394 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005395}
Guy Benyei11169dd2012-12-18 14:30:41 +00005396
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005397static inline void updateCursorAnnotation(CXCursor &Cursor,
5398 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005399 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005401 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005402}
5403
5404/// \brief It annotates and advances tokens with a cursor until the comparison
5405//// between the cursor location and the source range is the same as
5406/// \arg compResult.
5407///
5408/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5409/// Pass RangeOverlap to annotate tokens inside a range.
5410void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5411 RangeComparisonResult compResult,
5412 SourceRange range) {
5413 while (MoreTokens()) {
5414 const unsigned I = NextToken();
5415 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005416 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5417 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005418
5419 SourceLocation TokLoc = GetTokenLoc(I);
5420 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005421 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 AdvanceToken();
5423 continue;
5424 }
5425 break;
5426 }
5427}
5428
5429/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005430/// \returns true if it advanced beyond all macro tokens, false otherwise.
5431bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 CXCursor updateC,
5433 RangeComparisonResult compResult,
5434 SourceRange range) {
5435 assert(MoreTokens());
5436 assert(isFunctionMacroToken(NextToken()) &&
5437 "Should be called only for macro arg tokens");
5438
5439 // This works differently than annotateAndAdvanceTokens; because expanded
5440 // macro arguments can have arbitrary translation-unit source order, we do not
5441 // advance the token index one by one until a token fails the range test.
5442 // We only advance once past all of the macro arg tokens if all of them
5443 // pass the range test. If one of them fails we keep the token index pointing
5444 // at the start of the macro arg tokens so that the failing token will be
5445 // annotated by a subsequent annotation try.
5446
5447 bool atLeastOneCompFail = false;
5448
5449 unsigned I = NextToken();
5450 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5451 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5452 if (TokLoc.isFileID())
5453 continue; // not macro arg token, it's parens or comma.
5454 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5455 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5456 Cursors[I] = updateC;
5457 } else
5458 atLeastOneCompFail = true;
5459 }
5460
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005461 if (atLeastOneCompFail)
5462 return false;
5463
5464 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5465 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005466}
5467
5468enum CXChildVisitResult
5469AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 SourceRange cursorRange = getRawCursorExtent(cursor);
5471 if (cursorRange.isInvalid())
5472 return CXChildVisit_Recurse;
5473
5474 if (!HasContextSensitiveKeywords) {
5475 // Objective-C properties can have context-sensitive keywords.
5476 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005477 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5479 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5480 }
5481 // Objective-C methods can have context-sensitive keywords.
5482 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5483 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005484 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5486 if (Method->getObjCDeclQualifier())
5487 HasContextSensitiveKeywords = true;
5488 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005489 for (const auto *P : Method->params()) {
5490 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 HasContextSensitiveKeywords = true;
5492 break;
5493 }
5494 }
5495 }
5496 }
5497 }
5498 // C++ methods can have context-sensitive keywords.
5499 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005500 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5502 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5503 HasContextSensitiveKeywords = true;
5504 }
5505 }
5506 // C++ classes can have context-sensitive keywords.
5507 else if (cursor.kind == CXCursor_StructDecl ||
5508 cursor.kind == CXCursor_ClassDecl ||
5509 cursor.kind == CXCursor_ClassTemplate ||
5510 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005511 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 if (D->hasAttr<FinalAttr>())
5513 HasContextSensitiveKeywords = true;
5514 }
5515 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005516
5517 // Don't override a property annotation with its getter/setter method.
5518 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5519 parent.kind == CXCursor_ObjCPropertyDecl)
5520 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005521
5522 if (clang_isPreprocessing(cursor.kind)) {
5523 // Items in the preprocessing record are kept separate from items in
5524 // declarations, so we keep a separate token index.
5525 unsigned SavedTokIdx = TokIdx;
5526 TokIdx = PreprocessingTokIdx;
5527
5528 // Skip tokens up until we catch up to the beginning of the preprocessing
5529 // entry.
5530 while (MoreTokens()) {
5531 const unsigned I = NextToken();
5532 SourceLocation TokLoc = GetTokenLoc(I);
5533 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5534 case RangeBefore:
5535 AdvanceToken();
5536 continue;
5537 case RangeAfter:
5538 case RangeOverlap:
5539 break;
5540 }
5541 break;
5542 }
5543
5544 // Look at all of the tokens within this range.
5545 while (MoreTokens()) {
5546 const unsigned I = NextToken();
5547 SourceLocation TokLoc = GetTokenLoc(I);
5548 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5549 case RangeBefore:
5550 llvm_unreachable("Infeasible");
5551 case RangeAfter:
5552 break;
5553 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005554 // For macro expansions, just note where the beginning of the macro
5555 // expansion occurs.
5556 if (cursor.kind == CXCursor_MacroExpansion) {
5557 if (TokLoc == cursorRange.getBegin())
5558 Cursors[I] = cursor;
5559 AdvanceToken();
5560 break;
5561 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005562 // We may have already annotated macro names inside macro definitions.
5563 if (Cursors[I].kind != CXCursor_MacroExpansion)
5564 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 continue;
5567 }
5568 break;
5569 }
5570
5571 // Save the preprocessing token index; restore the non-preprocessing
5572 // token index.
5573 PreprocessingTokIdx = TokIdx;
5574 TokIdx = SavedTokIdx;
5575 return CXChildVisit_Recurse;
5576 }
5577
5578 if (cursorRange.isInvalid())
5579 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005580
5581 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 const enum CXCursorKind K = clang_getCursorKind(parent);
5584 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005585 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5586 // Attributes are annotated out-of-order, skip tokens until we reach it.
5587 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 ? clang_getNullCursor() : parent;
5589
5590 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5591
5592 // Avoid having the cursor of an expression "overwrite" the annotation of the
5593 // variable declaration that it belongs to.
5594 // This can happen for C++ constructor expressions whose range generally
5595 // include the variable declaration, e.g.:
5596 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005597 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005598 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005599 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 const unsigned I = NextToken();
5601 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5602 E->getLocStart() == D->getLocation() &&
5603 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005604 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005605 AdvanceToken();
5606 }
5607 }
5608 }
5609
5610 // Before recursing into the children keep some state that we are going
5611 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5612 // extra work after the child nodes are visited.
5613 // Note that we don't call VisitChildren here to avoid traversing statements
5614 // code-recursively which can blow the stack.
5615
5616 PostChildrenInfo Info;
5617 Info.Cursor = cursor;
5618 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005619 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 Info.BeforeChildrenTokenIdx = NextToken();
5621 PostChildrenInfos.push_back(Info);
5622
5623 return CXChildVisit_Recurse;
5624}
5625
5626bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5627 if (PostChildrenInfos.empty())
5628 return false;
5629 const PostChildrenInfo &Info = PostChildrenInfos.back();
5630 if (!clang_equalCursors(Info.Cursor, cursor))
5631 return false;
5632
5633 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5634 const unsigned AfterChildren = NextToken();
5635 SourceRange cursorRange = Info.CursorRange;
5636
5637 // Scan the tokens that are at the end of the cursor, but are not captured
5638 // but the child cursors.
5639 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5640
5641 // Scan the tokens that are at the beginning of the cursor, but are not
5642 // capture by the child cursors.
5643 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5644 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5645 break;
5646
5647 Cursors[I] = cursor;
5648 }
5649
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005650 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5651 // encountered the attribute cursor.
5652 if (clang_isAttribute(cursor.kind))
5653 TokIdx = Info.BeforeReachingCursorIdx;
5654
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 PostChildrenInfos.pop_back();
5656 return false;
5657}
5658
5659static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5660 CXCursor parent,
5661 CXClientData client_data) {
5662 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5663}
5664
5665static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5666 CXClientData client_data) {
5667 return static_cast<AnnotateTokensWorker*>(client_data)->
5668 postVisitChildren(cursor);
5669}
5670
5671namespace {
5672
5673/// \brief Uses the macro expansions in the preprocessing record to find
5674/// and mark tokens that are macro arguments. This info is used by the
5675/// AnnotateTokensWorker.
5676class MarkMacroArgTokensVisitor {
5677 SourceManager &SM;
5678 CXToken *Tokens;
5679 unsigned NumTokens;
5680 unsigned CurIdx;
5681
5682public:
5683 MarkMacroArgTokensVisitor(SourceManager &SM,
5684 CXToken *tokens, unsigned numTokens)
5685 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5686
5687 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5688 if (cursor.kind != CXCursor_MacroExpansion)
5689 return CXChildVisit_Continue;
5690
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005691 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 if (macroRange.getBegin() == macroRange.getEnd())
5693 return CXChildVisit_Continue; // it's not a function macro.
5694
5695 for (; CurIdx < NumTokens; ++CurIdx) {
5696 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5697 macroRange.getBegin()))
5698 break;
5699 }
5700
5701 if (CurIdx == NumTokens)
5702 return CXChildVisit_Break;
5703
5704 for (; CurIdx < NumTokens; ++CurIdx) {
5705 SourceLocation tokLoc = getTokenLoc(CurIdx);
5706 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5707 break;
5708
5709 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5710 }
5711
5712 if (CurIdx == NumTokens)
5713 return CXChildVisit_Break;
5714
5715 return CXChildVisit_Continue;
5716 }
5717
5718private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005719 CXToken &getTok(unsigned Idx) {
5720 assert(Idx < NumTokens);
5721 return Tokens[Idx];
5722 }
5723 const CXToken &getTok(unsigned Idx) const {
5724 assert(Idx < NumTokens);
5725 return Tokens[Idx];
5726 }
5727
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005729 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 }
5731
5732 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5733 // The third field is reserved and currently not used. Use it here
5734 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005735 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 }
5737};
5738
5739} // end anonymous namespace
5740
5741static CXChildVisitResult
5742MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5743 CXClientData client_data) {
5744 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5745 parent);
5746}
5747
5748namespace {
5749 struct clang_annotateTokens_Data {
5750 CXTranslationUnit TU;
5751 ASTUnit *CXXUnit;
5752 CXToken *Tokens;
5753 unsigned NumTokens;
5754 CXCursor *Cursors;
5755 };
5756}
5757
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758/// \brief Used by \c annotatePreprocessorTokens.
5759/// \returns true if lexing was finished, false otherwise.
5760static bool lexNext(Lexer &Lex, Token &Tok,
5761 unsigned &NextIdx, unsigned NumTokens) {
5762 if (NextIdx >= NumTokens)
5763 return true;
5764
5765 ++NextIdx;
5766 Lex.LexFromRawLexer(Tok);
5767 if (Tok.is(tok::eof))
5768 return true;
5769
5770 return false;
5771}
5772
Guy Benyei11169dd2012-12-18 14:30:41 +00005773static void annotatePreprocessorTokens(CXTranslationUnit TU,
5774 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005775 CXCursor *Cursors,
5776 CXToken *Tokens,
5777 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005778 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005779
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005780 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5782 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005783 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005785 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005786
5787 if (BeginLocInfo.first != EndLocInfo.first)
5788 return;
5789
5790 StringRef Buffer;
5791 bool Invalid = false;
5792 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5793 if (Buffer.empty() || Invalid)
5794 return;
5795
5796 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5797 CXXUnit->getASTContext().getLangOpts(),
5798 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5799 Buffer.end());
5800 Lex.SetCommentRetentionState(true);
5801
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005802 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 // Lex tokens in raw mode until we hit the end of the range, to avoid
5804 // entering #includes or expanding macros.
5805 while (true) {
5806 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005807 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5808 break;
5809 unsigned TokIdx = NextIdx-1;
5810 assert(Tok.getLocation() ==
5811 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005812
5813 reprocess:
5814 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005815 // We have found a preprocessing directive. Annotate the tokens
5816 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005817 //
5818 // FIXME: Some simple tests here could identify macro definitions and
5819 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005820
5821 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005822 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5823 break;
5824
Craig Topper69186e72014-06-08 08:38:04 +00005825 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005826 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005827 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5828 break;
5829
5830 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005831 IdentifierInfo &II =
5832 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005833 SourceLocation MappedTokLoc =
5834 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5835 MI = getMacroInfo(II, MappedTokLoc, TU);
5836 }
5837 }
5838
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005839 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005840 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005841 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5842 finished = true;
5843 break;
5844 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005845 // If we are in a macro definition, check if the token was ever a
5846 // macro name and annotate it if that's the case.
5847 if (MI) {
5848 SourceLocation SaveLoc = Tok.getLocation();
5849 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5850 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5851 Tok.setLocation(SaveLoc);
5852 if (MacroDef)
5853 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5854 Tok.getLocation(), TU);
5855 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005856 } while (!Tok.isAtStartOfLine());
5857
5858 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5859 assert(TokIdx <= LastIdx);
5860 SourceLocation EndLoc =
5861 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5862 CXCursor Cursor =
5863 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5864
5865 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005866 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005867
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005868 if (finished)
5869 break;
5870 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005871 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 }
5873}
5874
5875// This gets run a separate thread to avoid stack blowout.
5876static void clang_annotateTokensImpl(void *UserData) {
5877 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5878 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5879 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5880 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5881 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5882
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005883 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5885 setThreadBackgroundPriority();
5886
5887 // Determine the region of interest, which contains all of the tokens.
5888 SourceRange RegionOfInterest;
5889 RegionOfInterest.setBegin(
5890 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5891 RegionOfInterest.setEnd(
5892 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5893 Tokens[NumTokens-1])));
5894
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 // Relex the tokens within the source range to look for preprocessing
5896 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005897 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005898
5899 // If begin location points inside a macro argument, set it to the expansion
5900 // location so we can have the full context when annotating semantically.
5901 {
5902 SourceManager &SM = CXXUnit->getSourceManager();
5903 SourceLocation Loc =
5904 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5905 if (Loc.isMacroID())
5906 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5907 }
5908
Guy Benyei11169dd2012-12-18 14:30:41 +00005909 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5910 // Search and mark tokens that are macro argument expansions.
5911 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5912 Tokens, NumTokens);
5913 CursorVisitor MacroArgMarker(TU,
5914 MarkMacroArgTokensVisitorDelegate, &Visitor,
5915 /*VisitPreprocessorLast=*/true,
5916 /*VisitIncludedEntities=*/false,
5917 RegionOfInterest);
5918 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5919 }
5920
5921 // Annotate all of the source locations in the region of interest that map to
5922 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005923 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005924
5925 // FIXME: We use a ridiculous stack size here because the data-recursion
5926 // algorithm uses a large stack frame than the non-data recursive version,
5927 // and AnnotationTokensWorker currently transforms the data-recursion
5928 // algorithm back into a traditional recursion by explicitly calling
5929 // VisitChildren(). We will need to remove this explicit recursive call.
5930 W.AnnotateTokens();
5931
5932 // If we ran into any entities that involve context-sensitive keywords,
5933 // take another pass through the tokens to mark them as such.
5934 if (W.hasContextSensitiveKeywords()) {
5935 for (unsigned I = 0; I != NumTokens; ++I) {
5936 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5937 continue;
5938
5939 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5940 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005941 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5943 if (Property->getPropertyAttributesAsWritten() != 0 &&
5944 llvm::StringSwitch<bool>(II->getName())
5945 .Case("readonly", true)
5946 .Case("assign", true)
5947 .Case("unsafe_unretained", true)
5948 .Case("readwrite", true)
5949 .Case("retain", true)
5950 .Case("copy", true)
5951 .Case("nonatomic", true)
5952 .Case("atomic", true)
5953 .Case("getter", true)
5954 .Case("setter", true)
5955 .Case("strong", true)
5956 .Case("weak", true)
5957 .Default(false))
5958 Tokens[I].int_data[0] = CXToken_Keyword;
5959 }
5960 continue;
5961 }
5962
5963 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5964 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5965 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5966 if (llvm::StringSwitch<bool>(II->getName())
5967 .Case("in", true)
5968 .Case("out", true)
5969 .Case("inout", true)
5970 .Case("oneway", true)
5971 .Case("bycopy", true)
5972 .Case("byref", true)
5973 .Default(false))
5974 Tokens[I].int_data[0] = CXToken_Keyword;
5975 continue;
5976 }
5977
5978 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5979 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5980 Tokens[I].int_data[0] = CXToken_Keyword;
5981 continue;
5982 }
5983 }
5984 }
5985}
5986
5987extern "C" {
5988
5989void clang_annotateTokens(CXTranslationUnit TU,
5990 CXToken *Tokens, unsigned NumTokens,
5991 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005992 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005993 LOG_BAD_TU(TU);
5994 return;
5995 }
5996 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005997 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005999 }
6000
6001 LOG_FUNC_SECTION {
6002 *Log << TU << ' ';
6003 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6004 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6005 *Log << clang_getRange(bloc, eloc);
6006 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006007
6008 // Any token we don't specifically annotate will have a NULL cursor.
6009 CXCursor C = clang_getNullCursor();
6010 for (unsigned I = 0; I != NumTokens; ++I)
6011 Cursors[I] = C;
6012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 if (!CXXUnit)
6015 return;
6016
6017 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6018
6019 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6020 llvm::CrashRecoveryContext CRC;
6021 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6022 GetSafetyThreadStackSize() * 2)) {
6023 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6024 }
6025}
6026
6027} // end: extern "C"
6028
6029//===----------------------------------------------------------------------===//
6030// Operations for querying linkage of a cursor.
6031//===----------------------------------------------------------------------===//
6032
6033extern "C" {
6034CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6035 if (!clang_isDeclaration(cursor.kind))
6036 return CXLinkage_Invalid;
6037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006038 const Decl *D = cxcursor::getCursorDecl(cursor);
6039 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006040 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006041 case NoLinkage:
6042 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 case InternalLinkage: return CXLinkage_Internal;
6044 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6045 case ExternalLinkage: return CXLinkage_External;
6046 };
6047
6048 return CXLinkage_Invalid;
6049}
6050} // end: extern "C"
6051
6052//===----------------------------------------------------------------------===//
6053// Operations for querying language of a cursor.
6054//===----------------------------------------------------------------------===//
6055
6056static CXLanguageKind getDeclLanguage(const Decl *D) {
6057 if (!D)
6058 return CXLanguage_C;
6059
6060 switch (D->getKind()) {
6061 default:
6062 break;
6063 case Decl::ImplicitParam:
6064 case Decl::ObjCAtDefsField:
6065 case Decl::ObjCCategory:
6066 case Decl::ObjCCategoryImpl:
6067 case Decl::ObjCCompatibleAlias:
6068 case Decl::ObjCImplementation:
6069 case Decl::ObjCInterface:
6070 case Decl::ObjCIvar:
6071 case Decl::ObjCMethod:
6072 case Decl::ObjCProperty:
6073 case Decl::ObjCPropertyImpl:
6074 case Decl::ObjCProtocol:
6075 return CXLanguage_ObjC;
6076 case Decl::CXXConstructor:
6077 case Decl::CXXConversion:
6078 case Decl::CXXDestructor:
6079 case Decl::CXXMethod:
6080 case Decl::CXXRecord:
6081 case Decl::ClassTemplate:
6082 case Decl::ClassTemplatePartialSpecialization:
6083 case Decl::ClassTemplateSpecialization:
6084 case Decl::Friend:
6085 case Decl::FriendTemplate:
6086 case Decl::FunctionTemplate:
6087 case Decl::LinkageSpec:
6088 case Decl::Namespace:
6089 case Decl::NamespaceAlias:
6090 case Decl::NonTypeTemplateParm:
6091 case Decl::StaticAssert:
6092 case Decl::TemplateTemplateParm:
6093 case Decl::TemplateTypeParm:
6094 case Decl::UnresolvedUsingTypename:
6095 case Decl::UnresolvedUsingValue:
6096 case Decl::Using:
6097 case Decl::UsingDirective:
6098 case Decl::UsingShadow:
6099 return CXLanguage_CPlusPlus;
6100 }
6101
6102 return CXLanguage_C;
6103}
6104
6105extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106
6107static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6108 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6109 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006110
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006111 switch (D->getAvailability()) {
6112 case AR_Available:
6113 case AR_NotYetIntroduced:
6114 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006115 return getCursorAvailabilityForDecl(
6116 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006117 return CXAvailability_Available;
6118
6119 case AR_Deprecated:
6120 return CXAvailability_Deprecated;
6121
6122 case AR_Unavailable:
6123 return CXAvailability_NotAvailable;
6124 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006125
6126 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006127}
6128
Guy Benyei11169dd2012-12-18 14:30:41 +00006129enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6130 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6132 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006133
6134 return CXAvailability_Available;
6135}
6136
6137static CXVersion convertVersion(VersionTuple In) {
6138 CXVersion Out = { -1, -1, -1 };
6139 if (In.empty())
6140 return Out;
6141
6142 Out.Major = In.getMajor();
6143
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006144 Optional<unsigned> Minor = In.getMinor();
6145 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 Out.Minor = *Minor;
6147 else
6148 return Out;
6149
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006150 Optional<unsigned> Subminor = In.getSubminor();
6151 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 Out.Subminor = *Subminor;
6153
6154 return Out;
6155}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006156
6157static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6158 int *always_deprecated,
6159 CXString *deprecated_message,
6160 int *always_unavailable,
6161 CXString *unavailable_message,
6162 CXPlatformAvailability *availability,
6163 int availability_size) {
6164 bool HadAvailAttr = false;
6165 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006166 for (auto A : D->attrs()) {
6167 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006168 HadAvailAttr = true;
6169 if (always_deprecated)
6170 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006171 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006172 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006173 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006174 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006175 continue;
6176 }
6177
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006178 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006179 HadAvailAttr = true;
6180 if (always_unavailable)
6181 *always_unavailable = 1;
6182 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006183 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006184 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6185 }
6186 continue;
6187 }
6188
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006189 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006190 HadAvailAttr = true;
6191 if (N < availability_size) {
6192 availability[N].Platform
6193 = cxstring::createDup(Avail->getPlatform()->getName());
6194 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6195 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6196 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6197 availability[N].Unavailable = Avail->getUnavailable();
6198 availability[N].Message = cxstring::createDup(Avail->getMessage());
6199 }
6200 ++N;
6201 }
6202 }
6203
6204 if (!HadAvailAttr)
6205 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6206 return getCursorPlatformAvailabilityForDecl(
6207 cast<Decl>(EnumConst->getDeclContext()),
6208 always_deprecated,
6209 deprecated_message,
6210 always_unavailable,
6211 unavailable_message,
6212 availability,
6213 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006214
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006215 return N;
6216}
6217
Guy Benyei11169dd2012-12-18 14:30:41 +00006218int clang_getCursorPlatformAvailability(CXCursor cursor,
6219 int *always_deprecated,
6220 CXString *deprecated_message,
6221 int *always_unavailable,
6222 CXString *unavailable_message,
6223 CXPlatformAvailability *availability,
6224 int availability_size) {
6225 if (always_deprecated)
6226 *always_deprecated = 0;
6227 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006228 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 if (always_unavailable)
6230 *always_unavailable = 0;
6231 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006232 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006233
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 if (!clang_isDeclaration(cursor.kind))
6235 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006236
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006237 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 if (!D)
6239 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006240
6241 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6242 deprecated_message,
6243 always_unavailable,
6244 unavailable_message,
6245 availability,
6246 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006247}
6248
6249void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6250 clang_disposeString(availability->Platform);
6251 clang_disposeString(availability->Message);
6252}
6253
6254CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6255 if (clang_isDeclaration(cursor.kind))
6256 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6257
6258 return CXLanguage_Invalid;
6259}
6260
6261 /// \brief If the given cursor is the "templated" declaration
6262 /// descibing a class or function template, return the class or
6263 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006264static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006265 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006266 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006268 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006269 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6270 return FunTmpl;
6271
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006272 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006273 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6274 return ClassTmpl;
6275
6276 return D;
6277}
6278
6279CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6280 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006281 if (const Decl *D = getCursorDecl(cursor)) {
6282 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 if (!DC)
6284 return clang_getNullCursor();
6285
6286 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6287 getCursorTU(cursor));
6288 }
6289 }
6290
6291 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006292 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 return MakeCXCursor(D, getCursorTU(cursor));
6294 }
6295
6296 return clang_getNullCursor();
6297}
6298
6299CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6300 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006301 if (const Decl *D = getCursorDecl(cursor)) {
6302 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 if (!DC)
6304 return clang_getNullCursor();
6305
6306 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6307 getCursorTU(cursor));
6308 }
6309 }
6310
6311 // FIXME: Note that we can't easily compute the lexical context of a
6312 // statement or expression, so we return nothing.
6313 return clang_getNullCursor();
6314}
6315
6316CXFile clang_getIncludedFile(CXCursor cursor) {
6317 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006318 return nullptr;
6319
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006320 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006321 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006322}
6323
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006324unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6325 if (C.kind != CXCursor_ObjCPropertyDecl)
6326 return CXObjCPropertyAttr_noattr;
6327
6328 unsigned Result = CXObjCPropertyAttr_noattr;
6329 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6330 ObjCPropertyDecl::PropertyAttributeKind Attr =
6331 PD->getPropertyAttributesAsWritten();
6332
6333#define SET_CXOBJCPROP_ATTR(A) \
6334 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6335 Result |= CXObjCPropertyAttr_##A
6336 SET_CXOBJCPROP_ATTR(readonly);
6337 SET_CXOBJCPROP_ATTR(getter);
6338 SET_CXOBJCPROP_ATTR(assign);
6339 SET_CXOBJCPROP_ATTR(readwrite);
6340 SET_CXOBJCPROP_ATTR(retain);
6341 SET_CXOBJCPROP_ATTR(copy);
6342 SET_CXOBJCPROP_ATTR(nonatomic);
6343 SET_CXOBJCPROP_ATTR(setter);
6344 SET_CXOBJCPROP_ATTR(atomic);
6345 SET_CXOBJCPROP_ATTR(weak);
6346 SET_CXOBJCPROP_ATTR(strong);
6347 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6348#undef SET_CXOBJCPROP_ATTR
6349
6350 return Result;
6351}
6352
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006353unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6354 if (!clang_isDeclaration(C.kind))
6355 return CXObjCDeclQualifier_None;
6356
6357 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6358 const Decl *D = getCursorDecl(C);
6359 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6360 QT = MD->getObjCDeclQualifier();
6361 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6362 QT = PD->getObjCDeclQualifier();
6363 if (QT == Decl::OBJC_TQ_None)
6364 return CXObjCDeclQualifier_None;
6365
6366 unsigned Result = CXObjCDeclQualifier_None;
6367 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6368 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6369 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6370 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6371 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6372 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6373
6374 return Result;
6375}
6376
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006377unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6378 if (!clang_isDeclaration(C.kind))
6379 return 0;
6380
6381 const Decl *D = getCursorDecl(C);
6382 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6383 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6384 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6385 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6386
6387 return 0;
6388}
6389
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006390unsigned clang_Cursor_isVariadic(CXCursor C) {
6391 if (!clang_isDeclaration(C.kind))
6392 return 0;
6393
6394 const Decl *D = getCursorDecl(C);
6395 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6396 return FD->isVariadic();
6397 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6398 return MD->isVariadic();
6399
6400 return 0;
6401}
6402
Guy Benyei11169dd2012-12-18 14:30:41 +00006403CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6404 if (!clang_isDeclaration(C.kind))
6405 return clang_getNullRange();
6406
6407 const Decl *D = getCursorDecl(C);
6408 ASTContext &Context = getCursorContext(C);
6409 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6410 if (!RC)
6411 return clang_getNullRange();
6412
6413 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6414}
6415
6416CXString clang_Cursor_getRawCommentText(CXCursor C) {
6417 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006418 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006419
6420 const Decl *D = getCursorDecl(C);
6421 ASTContext &Context = getCursorContext(C);
6422 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6423 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6424 StringRef();
6425
6426 // Don't duplicate the string because RawText points directly into source
6427 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006428 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006429}
6430
6431CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6432 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006433 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006434
6435 const Decl *D = getCursorDecl(C);
6436 const ASTContext &Context = getCursorContext(C);
6437 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6438
6439 if (RC) {
6440 StringRef BriefText = RC->getBriefText(Context);
6441
6442 // Don't duplicate the string because RawComment ensures that this memory
6443 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006444 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 }
6446
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006447 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006448}
6449
Guy Benyei11169dd2012-12-18 14:30:41 +00006450CXModule clang_Cursor_getModule(CXCursor C) {
6451 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006452 if (const ImportDecl *ImportD =
6453 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 return ImportD->getImportedModule();
6455 }
6456
Craig Topper69186e72014-06-08 08:38:04 +00006457 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006458}
6459
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006460CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6461 if (isNotUsableTU(TU)) {
6462 LOG_BAD_TU(TU);
6463 return nullptr;
6464 }
6465 if (!File)
6466 return nullptr;
6467 FileEntry *FE = static_cast<FileEntry *>(File);
6468
6469 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6470 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6471 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6472
6473 if (Module *Mod = Header.getModule()) {
6474 if (Header.getRole() != ModuleMap::ExcludedHeader)
6475 return Mod;
6476 }
6477 return nullptr;
6478}
6479
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006480CXFile clang_Module_getASTFile(CXModule CXMod) {
6481 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006482 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006483 Module *Mod = static_cast<Module*>(CXMod);
6484 return const_cast<FileEntry *>(Mod->getASTFile());
6485}
6486
Guy Benyei11169dd2012-12-18 14:30:41 +00006487CXModule clang_Module_getParent(CXModule CXMod) {
6488 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006489 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006490 Module *Mod = static_cast<Module*>(CXMod);
6491 return Mod->Parent;
6492}
6493
6494CXString clang_Module_getName(CXModule CXMod) {
6495 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006496 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006497 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006498 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006499}
6500
6501CXString clang_Module_getFullName(CXModule CXMod) {
6502 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006503 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006505 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006506}
6507
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006508int clang_Module_isSystem(CXModule CXMod) {
6509 if (!CXMod)
6510 return 0;
6511 Module *Mod = static_cast<Module*>(CXMod);
6512 return Mod->IsSystem;
6513}
6514
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006515unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6516 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006517 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006518 LOG_BAD_TU(TU);
6519 return 0;
6520 }
6521 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 return 0;
6523 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006524 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6525 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6526 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006527}
6528
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006529CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6530 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006531 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006532 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006533 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006534 }
6535 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006536 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006538 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006539
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006540 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6541 if (Index < TopHeaders.size())
6542 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006543
Craig Topper69186e72014-06-08 08:38:04 +00006544 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006545}
6546
6547} // end: extern "C"
6548
6549//===----------------------------------------------------------------------===//
6550// C++ AST instrospection.
6551//===----------------------------------------------------------------------===//
6552
6553extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006554unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6555 if (!clang_isDeclaration(C.kind))
6556 return 0;
6557
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006558 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006559 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006560 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006561 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6562}
6563
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006564unsigned clang_CXXMethod_isConst(CXCursor C) {
6565 if (!clang_isDeclaration(C.kind))
6566 return 0;
6567
6568 const Decl *D = cxcursor::getCursorDecl(C);
6569 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006570 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006571 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6572}
6573
Guy Benyei11169dd2012-12-18 14:30:41 +00006574unsigned clang_CXXMethod_isStatic(CXCursor C) {
6575 if (!clang_isDeclaration(C.kind))
6576 return 0;
6577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006578 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006579 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006580 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 return (Method && Method->isStatic()) ? 1 : 0;
6582}
6583
6584unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6585 if (!clang_isDeclaration(C.kind))
6586 return 0;
6587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006588 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006589 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006590 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 return (Method && Method->isVirtual()) ? 1 : 0;
6592}
6593} // end: extern "C"
6594
6595//===----------------------------------------------------------------------===//
6596// Attribute introspection.
6597//===----------------------------------------------------------------------===//
6598
6599extern "C" {
6600CXType clang_getIBOutletCollectionType(CXCursor C) {
6601 if (C.kind != CXCursor_IBOutletCollectionAttr)
6602 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6603
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006604 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006605 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6606
6607 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6608}
6609} // end: extern "C"
6610
6611//===----------------------------------------------------------------------===//
6612// Inspecting memory usage.
6613//===----------------------------------------------------------------------===//
6614
6615typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6616
6617static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6618 enum CXTUResourceUsageKind k,
6619 unsigned long amount) {
6620 CXTUResourceUsageEntry entry = { k, amount };
6621 entries.push_back(entry);
6622}
6623
6624extern "C" {
6625
6626const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6627 const char *str = "";
6628 switch (kind) {
6629 case CXTUResourceUsage_AST:
6630 str = "ASTContext: expressions, declarations, and types";
6631 break;
6632 case CXTUResourceUsage_Identifiers:
6633 str = "ASTContext: identifiers";
6634 break;
6635 case CXTUResourceUsage_Selectors:
6636 str = "ASTContext: selectors";
6637 break;
6638 case CXTUResourceUsage_GlobalCompletionResults:
6639 str = "Code completion: cached global results";
6640 break;
6641 case CXTUResourceUsage_SourceManagerContentCache:
6642 str = "SourceManager: content cache allocator";
6643 break;
6644 case CXTUResourceUsage_AST_SideTables:
6645 str = "ASTContext: side tables";
6646 break;
6647 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6648 str = "SourceManager: malloc'ed memory buffers";
6649 break;
6650 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6651 str = "SourceManager: mmap'ed memory buffers";
6652 break;
6653 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6654 str = "ExternalASTSource: malloc'ed memory buffers";
6655 break;
6656 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6657 str = "ExternalASTSource: mmap'ed memory buffers";
6658 break;
6659 case CXTUResourceUsage_Preprocessor:
6660 str = "Preprocessor: malloc'ed memory";
6661 break;
6662 case CXTUResourceUsage_PreprocessingRecord:
6663 str = "Preprocessor: PreprocessingRecord";
6664 break;
6665 case CXTUResourceUsage_SourceManager_DataStructures:
6666 str = "SourceManager: data structures and tables";
6667 break;
6668 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6669 str = "Preprocessor: header search tables";
6670 break;
6671 }
6672 return str;
6673}
6674
6675CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006676 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006677 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006678 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 return usage;
6680 }
6681
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006682 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006683 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 ASTContext &astContext = astUnit->getASTContext();
6685
6686 // How much memory is used by AST nodes and types?
6687 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6688 (unsigned long) astContext.getASTAllocatedMemory());
6689
6690 // How much memory is used by identifiers?
6691 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6692 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6693
6694 // How much memory is used for selectors?
6695 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6696 (unsigned long) astContext.Selectors.getTotalMemory());
6697
6698 // How much memory is used by ASTContext's side tables?
6699 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6700 (unsigned long) astContext.getSideTableAllocatedMemory());
6701
6702 // How much memory is used for caching global code completion results?
6703 unsigned long completionBytes = 0;
6704 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006705 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006706 completionBytes = completionAllocator->getTotalMemory();
6707 }
6708 createCXTUResourceUsageEntry(*entries,
6709 CXTUResourceUsage_GlobalCompletionResults,
6710 completionBytes);
6711
6712 // How much memory is being used by SourceManager's content cache?
6713 createCXTUResourceUsageEntry(*entries,
6714 CXTUResourceUsage_SourceManagerContentCache,
6715 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6716
6717 // How much memory is being used by the MemoryBuffer's in SourceManager?
6718 const SourceManager::MemoryBufferSizes &srcBufs =
6719 astUnit->getSourceManager().getMemoryBufferSizes();
6720
6721 createCXTUResourceUsageEntry(*entries,
6722 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6723 (unsigned long) srcBufs.malloc_bytes);
6724 createCXTUResourceUsageEntry(*entries,
6725 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6726 (unsigned long) srcBufs.mmap_bytes);
6727 createCXTUResourceUsageEntry(*entries,
6728 CXTUResourceUsage_SourceManager_DataStructures,
6729 (unsigned long) astContext.getSourceManager()
6730 .getDataStructureSizes());
6731
6732 // How much memory is being used by the ExternalASTSource?
6733 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6734 const ExternalASTSource::MemoryBufferSizes &sizes =
6735 esrc->getMemoryBufferSizes();
6736
6737 createCXTUResourceUsageEntry(*entries,
6738 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6739 (unsigned long) sizes.malloc_bytes);
6740 createCXTUResourceUsageEntry(*entries,
6741 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6742 (unsigned long) sizes.mmap_bytes);
6743 }
6744
6745 // How much memory is being used by the Preprocessor?
6746 Preprocessor &pp = astUnit->getPreprocessor();
6747 createCXTUResourceUsageEntry(*entries,
6748 CXTUResourceUsage_Preprocessor,
6749 pp.getTotalMemory());
6750
6751 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6752 createCXTUResourceUsageEntry(*entries,
6753 CXTUResourceUsage_PreprocessingRecord,
6754 pRec->getTotalMemory());
6755 }
6756
6757 createCXTUResourceUsageEntry(*entries,
6758 CXTUResourceUsage_Preprocessor_HeaderSearch,
6759 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006760
Guy Benyei11169dd2012-12-18 14:30:41 +00006761 CXTUResourceUsage usage = { (void*) entries.get(),
6762 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006763 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006764 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 return usage;
6766}
6767
6768void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6769 if (usage.data)
6770 delete (MemUsageEntries*) usage.data;
6771}
6772
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006773CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6774 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006775 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006776 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006777
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006778 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006779 LOG_BAD_TU(TU);
6780 return skipped;
6781 }
6782
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006783 if (!file)
6784 return skipped;
6785
6786 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6787 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6788 if (!ppRec)
6789 return skipped;
6790
6791 ASTContext &Ctx = astUnit->getASTContext();
6792 SourceManager &sm = Ctx.getSourceManager();
6793 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6794 FileID wantedFileID = sm.translateFile(fileEntry);
6795
6796 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6797 std::vector<SourceRange> wantedRanges;
6798 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6799 i != ei; ++i) {
6800 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6801 wantedRanges.push_back(*i);
6802 }
6803
6804 skipped->count = wantedRanges.size();
6805 skipped->ranges = new CXSourceRange[skipped->count];
6806 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6807 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6808
6809 return skipped;
6810}
6811
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006812void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6813 if (ranges) {
6814 delete[] ranges->ranges;
6815 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006816 }
6817}
6818
Guy Benyei11169dd2012-12-18 14:30:41 +00006819} // end extern "C"
6820
6821void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6822 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6823 for (unsigned I = 0; I != Usage.numEntries; ++I)
6824 fprintf(stderr, " %s: %lu\n",
6825 clang_getTUResourceUsageName(Usage.entries[I].kind),
6826 Usage.entries[I].amount);
6827
6828 clang_disposeCXTUResourceUsage(Usage);
6829}
6830
6831//===----------------------------------------------------------------------===//
6832// Misc. utility functions.
6833//===----------------------------------------------------------------------===//
6834
6835/// Default to using an 8 MB stack size on "safety" threads.
6836static unsigned SafetyStackThreadSize = 8 << 20;
6837
6838namespace clang {
6839
6840bool RunSafely(llvm::CrashRecoveryContext &CRC,
6841 void (*Fn)(void*), void *UserData,
6842 unsigned Size) {
6843 if (!Size)
6844 Size = GetSafetyThreadStackSize();
6845 if (Size)
6846 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6847 return CRC.RunSafely(Fn, UserData);
6848}
6849
6850unsigned GetSafetyThreadStackSize() {
6851 return SafetyStackThreadSize;
6852}
6853
6854void SetSafetyThreadStackSize(unsigned Value) {
6855 SafetyStackThreadSize = Value;
6856}
6857
6858}
6859
6860void clang::setThreadBackgroundPriority() {
6861 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6862 return;
6863
Alp Toker1a86ad22014-07-06 06:24:00 +00006864#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006865 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6866#endif
6867}
6868
6869void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6870 if (!Unit)
6871 return;
6872
6873 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6874 DEnd = Unit->stored_diag_end();
6875 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006876 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006877 CXString Msg = clang_formatDiagnostic(&Diag,
6878 clang_defaultDiagnosticDisplayOptions());
6879 fprintf(stderr, "%s\n", clang_getCString(Msg));
6880 clang_disposeString(Msg);
6881 }
6882#ifdef LLVM_ON_WIN32
6883 // On Windows, force a flush, since there may be multiple copies of
6884 // stderr and stdout in the file system, all with different buffers
6885 // but writing to the same device.
6886 fflush(stderr);
6887#endif
6888}
6889
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006890MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6891 SourceLocation MacroDefLoc,
6892 CXTranslationUnit TU){
6893 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006895 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006897
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006898 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006899 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006900 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006901 if (MD) {
6902 for (MacroDirective::DefInfo
6903 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6904 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6905 return Def.getMacroInfo();
6906 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006907 }
6908
Craig Topper69186e72014-06-08 08:38:04 +00006909 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006910}
6911
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006912const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6913 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006914 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006916 const IdentifierInfo *II = MacroDef->getName();
6917 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006919
6920 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6921}
6922
6923MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6924 const Token &Tok,
6925 CXTranslationUnit TU) {
6926 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006927 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006928 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006929 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006930
6931 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006932 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006933 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6934 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006935 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936
6937 // Check that the token is inside the definition and not its argument list.
6938 SourceManager &SM = Unit->getSourceManager();
6939 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006940 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006941 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006942 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006943
6944 Preprocessor &PP = Unit->getPreprocessor();
6945 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6946 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006947 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006948
Alp Toker2d57cea2014-05-17 04:53:25 +00006949 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006950 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006951 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006952
6953 // Check that the identifier is not one of the macro arguments.
6954 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006955 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006956
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006957 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6958 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006959 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006960
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006961 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006962}
6963
6964MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6965 SourceLocation Loc,
6966 CXTranslationUnit TU) {
6967 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006968 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006969
6970 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006971 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006972 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006973 Preprocessor &PP = Unit->getPreprocessor();
6974 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006975 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006976 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6977 Token Tok;
6978 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006979 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006980
6981 return checkForMacroInMacroDefinition(MI, Tok, TU);
6982}
6983
Guy Benyei11169dd2012-12-18 14:30:41 +00006984extern "C" {
6985
6986CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006987 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006988}
6989
6990} // end: extern "C"
6991
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006992Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6993 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006994 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006995 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006996 if (Unit->isMainFileAST())
6997 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006998 return *this;
6999 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007000 } else {
7001 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007002 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007003 return *this;
7004}
7005
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007006Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7007 *this << FE->getName();
7008 return *this;
7009}
7010
7011Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7012 CXString cursorName = clang_getCursorDisplayName(cursor);
7013 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7014 clang_disposeString(cursorName);
7015 return *this;
7016}
7017
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007018Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7019 CXFile File;
7020 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007021 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007022 CXString FileName = clang_getFileName(File);
7023 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7024 clang_disposeString(FileName);
7025 return *this;
7026}
7027
7028Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7029 CXSourceLocation BLoc = clang_getRangeStart(range);
7030 CXSourceLocation ELoc = clang_getRangeEnd(range);
7031
7032 CXFile BFile;
7033 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007034 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007035
7036 CXFile EFile;
7037 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007038 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007039
7040 CXString BFileName = clang_getFileName(BFile);
7041 if (BFile == EFile) {
7042 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7043 BLine, BColumn, ELine, EColumn);
7044 } else {
7045 CXString EFileName = clang_getFileName(EFile);
7046 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7047 BLine, BColumn)
7048 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7049 ELine, EColumn);
7050 clang_disposeString(EFileName);
7051 }
7052 clang_disposeString(BFileName);
7053 return *this;
7054}
7055
7056Logger &cxindex::Logger::operator<<(CXString Str) {
7057 *this << clang_getCString(Str);
7058 return *this;
7059}
7060
7061Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7062 LogOS << Fmt;
7063 return *this;
7064}
7065
Chandler Carruth37ad2582014-06-27 15:14:39 +00007066static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7067
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007068cxindex::Logger::~Logger() {
7069 LogOS.flush();
7070
Chandler Carruth37ad2582014-06-27 15:14:39 +00007071 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007072
7073 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7074
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007075 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007076 OS << "[libclang:" << Name << ':';
7077
Alp Toker1a86ad22014-07-06 06:24:00 +00007078#ifdef USE_DARWIN_THREADS
7079 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007080 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7081 OS << tid << ':';
7082#endif
7083
7084 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7085 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7086 OS << Msg.str() << '\n';
7087
7088 if (Trace) {
7089 llvm::sys::PrintStackTrace(stderr);
7090 OS << "--------------------------------------------------\n";
7091 }
7092}