blob: fe46e3b4d1591e7d6a90a1b7617592342bf13cde [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869
Guy Benyei11169dd2012-12-18 14:30:41 +00001870private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1873 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1875 void AddStmt(const Stmt *S);
1876 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001879 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001880};
1881} // end anonyous namespace
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 // 'S' should always be non-null, since it comes from the
1885 // statement we are visiting.
1886 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1887}
1888
1889void
1890EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1891 if (Qualifier)
1892 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1893}
1894
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 if (S)
1897 WL.push_back(StmtVisit(S, Parent));
1898}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001899void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001900 if (D)
1901 WL.push_back(DeclVisit(D, Parent, isFirst));
1902}
1903void EnqueueVisitor::
1904 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1905 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001907}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 if (D)
1910 WL.push_back(MemberRefVisit(D, L, Parent));
1911}
1912void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1913 if (TI)
1914 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1915 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001916void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 AddStmt(*Child);
1920 }
1921 if (size == WL.size())
1922 return;
1923 // Now reverse the entries we just added. This will match the DFS
1924 // ordering performed by the worklist.
1925 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1926 std::reverse(I, E);
1927}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001928namespace {
1929class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1930 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001931 /// \brief Process clauses with list of variables.
1932 template <typename T>
1933 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001934public:
1935 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1936#define OPENMP_CLAUSE(Name, Class) \
1937 void Visit##Class(const Class *C);
1938#include "clang/Basic/OpenMPKinds.def"
1939};
1940
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001941void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1942 Visitor->AddStmt(C->getCondition());
1943}
1944
Alexey Bataev3778b602014-07-17 07:32:53 +00001945void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1946 Visitor->AddStmt(C->getCondition());
1947}
1948
Alexey Bataev568a8332014-03-06 06:15:19 +00001949void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1950 Visitor->AddStmt(C->getNumThreads());
1951}
1952
Alexey Bataev62c87d22014-03-21 04:51:18 +00001953void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1954 Visitor->AddStmt(C->getSafelen());
1955}
1956
Alexander Musman8bd31e62014-05-27 15:12:19 +00001957void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1958 Visitor->AddStmt(C->getNumForLoops());
1959}
1960
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001962
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001963void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1964
Alexey Bataev56dafe82014-06-20 07:16:17 +00001965void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1966 Visitor->AddStmt(C->getChunkSize());
1967}
1968
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001969void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1970
Alexey Bataev236070f2014-06-20 11:19:47 +00001971void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1972
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001973void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1974
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001975void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1976
Alexey Bataev756c1962013-09-24 03:17:45 +00001977template<typename T>
1978void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001979 for (const auto *I : Node->varlists())
1980 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001981}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001982
1983void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001984 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001985}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001986void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1987 const OMPFirstprivateClause *C) {
1988 VisitOMPClauseList(C);
1989}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001990void OMPClauseEnqueue::VisitOMPLastprivateClause(
1991 const OMPLastprivateClause *C) {
1992 VisitOMPClauseList(C);
1993}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001994void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001995 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001996}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001997void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1998 VisitOMPClauseList(C);
1999}
Alexander Musman8dba6642014-04-22 13:09:42 +00002000void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2001 VisitOMPClauseList(C);
2002 Visitor->AddStmt(C->getStep());
2003}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002004void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2005 VisitOMPClauseList(C);
2006 Visitor->AddStmt(C->getAlignment());
2007}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002008void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2009 VisitOMPClauseList(C);
2010}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002011void
2012OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002015}
Alexey Bataev756c1962013-09-24 03:17:45 +00002016
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2018 unsigned size = WL.size();
2019 OMPClauseEnqueue Visitor(this);
2020 Visitor.Visit(S);
2021 if (size == WL.size())
2022 return;
2023 // Now reverse the entries we just added. This will match the DFS
2024 // ordering performed by the worklist.
2025 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2026 std::reverse(I, E);
2027}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2030}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002032 AddDecl(B->getBlockDecl());
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 EnqueueChildren(E);
2036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2039 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 E = S->body_rend(); I != E; ++I) {
2041 AddStmt(*I);
2042 }
2043}
2044void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 AddStmt(S->getSubStmt());
2047 AddDeclarationNameInfo(S);
2048 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2049 AddNestedNameSpecifierLoc(QualifierLoc);
2050}
2051
2052void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2055 AddDeclarationNameInfo(E);
2056 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2057 AddNestedNameSpecifierLoc(QualifierLoc);
2058 if (!E->isImplicitAccess())
2059 AddStmt(E->getBase());
2060}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 // Enqueue the initializer , if any.
2063 AddStmt(E->getInitializer());
2064 // Enqueue the array size, if any.
2065 AddStmt(E->getArraySize());
2066 // Enqueue the allocated type.
2067 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2068 // Enqueue the placement arguments.
2069 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2070 AddStmt(E->getPlacementArg(I-1));
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2074 AddStmt(CE->getArg(I-1));
2075 AddStmt(CE->getCallee());
2076 AddStmt(CE->getArg(0));
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2079 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 // Visit the name of the type being destroyed.
2081 AddTypeLoc(E->getDestroyedTypeInfo());
2082 // Visit the scope type that looks disturbingly like the nested-name-specifier
2083 // but isn't.
2084 AddTypeLoc(E->getScopeTypeInfo());
2085 // Visit the nested-name-specifier.
2086 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2087 AddNestedNameSpecifierLoc(QualifierLoc);
2088 // Visit base expression.
2089 AddStmt(E->getBase());
2090}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2092 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 AddTypeLoc(E->getTypeSourceInfo());
2094}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2096 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 EnqueueChildren(E);
2098 AddTypeLoc(E->getTypeSourceInfo());
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 EnqueueChildren(E);
2102 if (E->isTypeOperand())
2103 AddTypeLoc(E->getTypeOperandSourceInfo());
2104}
2105
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2107 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 EnqueueChildren(E);
2109 AddTypeLoc(E->getTypeSourceInfo());
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 EnqueueChildren(E);
2113 if (E->isTypeOperand())
2114 AddTypeLoc(E->getTypeOperandSourceInfo());
2115}
2116
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 EnqueueChildren(S);
2119 AddDecl(S->getExceptionDecl());
2120}
2121
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 if (DR->hasExplicitTemplateArgs()) {
2124 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2125 }
2126 WL.push_back(DeclRefExprParts(DR, Parent));
2127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2129 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2131 AddDeclarationNameInfo(E);
2132 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 unsigned size = WL.size();
2136 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002137 for (const auto *D : S->decls()) {
2138 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 isFirst = false;
2140 }
2141 if (size == WL.size())
2142 return;
2143 // Now reverse the entries we just added. This will match the DFS
2144 // ordering performed by the worklist.
2145 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2146 std::reverse(I, E);
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 D = E->designators_rbegin(), DEnd = E->designators_rend();
2152 D != DEnd; ++D) {
2153 if (D->isFieldDesignator()) {
2154 if (FieldDecl *Field = D->getField())
2155 AddMemberRef(Field, D->getFieldLoc());
2156 continue;
2157 }
2158 if (D->isArrayDesignator()) {
2159 AddStmt(E->getArrayIndex(*D));
2160 continue;
2161 }
2162 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2163 AddStmt(E->getArrayRangeEnd(*D));
2164 AddStmt(E->getArrayRangeStart(*D));
2165 }
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 EnqueueChildren(E);
2169 AddTypeLoc(E->getTypeInfoAsWritten());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 AddStmt(FS->getBody());
2173 AddStmt(FS->getInc());
2174 AddStmt(FS->getCond());
2175 AddDecl(FS->getConditionVariable());
2176 AddStmt(FS->getInit());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddStmt(If->getElse());
2183 AddStmt(If->getThen());
2184 AddStmt(If->getCond());
2185 AddDecl(If->getConditionVariable());
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 // We care about the syntactic form of the initializer list, only.
2189 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2190 IE = Syntactic;
2191 EnqueueChildren(IE);
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 WL.push_back(MemberExprParts(M, Parent));
2195
2196 // If the base of the member access expression is an implicit 'this', don't
2197 // visit it.
2198 // FIXME: If we ever want to show these implicit accesses, this will be
2199 // unfortunate. However, clang_getCursor() relies on this behavior.
2200 if (!M->isImplicitAccess())
2201 AddStmt(M->getBase());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 AddTypeLoc(E->getEncodedTypeSourceInfo());
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 EnqueueChildren(M);
2208 AddTypeLoc(M->getClassReceiverTypeInfo());
2209}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 // Visit the components of the offsetof expression.
2212 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2213 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2214 const OffsetOfNode &Node = E->getComponent(I-1);
2215 switch (Node.getKind()) {
2216 case OffsetOfNode::Array:
2217 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2218 break;
2219 case OffsetOfNode::Field:
2220 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2221 break;
2222 case OffsetOfNode::Identifier:
2223 case OffsetOfNode::Base:
2224 continue;
2225 }
2226 }
2227 // Visit the type into which we're computing the offset.
2228 AddTypeLoc(E->getTypeSourceInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2232 WL.push_back(OverloadExprParts(E, Parent));
2233}
2234void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 EnqueueChildren(E);
2237 if (E->isArgumentType())
2238 AddTypeLoc(E->getArgumentTypeInfo());
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 EnqueueChildren(S);
2242}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 AddStmt(S->getBody());
2245 AddStmt(S->getCond());
2246 AddDecl(S->getConditionVariable());
2247}
2248
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 AddStmt(W->getBody());
2251 AddStmt(W->getCond());
2252 AddDecl(W->getConditionVariable());
2253}
2254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 for (unsigned I = E->getNumArgs(); I > 0; --I)
2257 AddTypeLoc(E->getArg(I-1));
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddTypeLoc(E->getQueriedTypeSourceInfo());
2262}
2263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 EnqueueChildren(E);
2266}
2267
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 VisitOverloadExpr(U);
2270 if (!U->isImplicitAccess())
2271 AddStmt(U->getBase());
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(E->getSubExpr());
2275 AddTypeLoc(E->getWrittenTypeInfo());
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 WL.push_back(SizeOfPackExprParts(E, Parent));
2279}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 // If the opaque value has a source expression, just transparently
2282 // visit that. This is useful for (e.g.) pseudo-object expressions.
2283 if (Expr *SourceExpr = E->getSourceExpr())
2284 return Visit(SourceExpr);
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 AddStmt(E->getBody());
2288 WL.push_back(LambdaExprParts(E, Parent));
2289}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 // Treat the expression like its syntactic form.
2292 Visit(E->getSyntacticForm());
2293}
2294
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002295void EnqueueVisitor::VisitOMPExecutableDirective(
2296 const OMPExecutableDirective *D) {
2297 EnqueueChildren(D);
2298 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2299 E = D->clauses().end();
2300 I != E; ++I)
2301 EnqueueChildren(*I);
2302}
2303
2304void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2305 VisitOMPExecutableDirective(D);
2306}
2307
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002308void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2309 VisitOMPExecutableDirective(D);
2310}
2311
Alexey Bataevf29276e2014-06-18 04:14:57 +00002312void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2313 VisitOMPExecutableDirective(D);
2314}
2315
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002316void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002320void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2321 VisitOMPExecutableDirective(D);
2322}
2323
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002324void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexander Musman80c22892014-07-17 08:54:58 +00002328void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataev4acb8592014-07-07 13:01:15 +00002332void
2333EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2334 VisitOMPExecutableDirective(D);
2335}
2336
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002337void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2338 const OMPParallelSectionsDirective *D) {
2339 VisitOMPExecutableDirective(D);
2340}
2341
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002342void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2343 VisitOMPExecutableDirective(D);
2344}
2345
Alexey Bataev68446b72014-07-18 07:47:19 +00002346void
2347EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2348 VisitOMPExecutableDirective(D);
2349}
2350
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002351void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2352 VisitOMPExecutableDirective(D);
2353}
2354
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2357}
2358
2359bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2360 if (RegionOfInterest.isValid()) {
2361 SourceRange Range = getRawCursorExtent(C);
2362 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2363 return false;
2364 }
2365 return true;
2366}
2367
2368bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2369 while (!WL.empty()) {
2370 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002371 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002372
2373 // Set the Parent field, then back to its old value once we're done.
2374 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2375
2376 switch (LI.getKind()) {
2377 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 if (!D)
2380 continue;
2381
2382 // For now, perform default visitation for Decls.
2383 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2384 cast<DeclVisit>(&LI)->isFirst())))
2385 return true;
2386
2387 continue;
2388 }
2389 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2390 const ASTTemplateArgumentListInfo *ArgList =
2391 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2392 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2393 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2394 Arg != ArgEnd; ++Arg) {
2395 if (VisitTemplateArgumentLoc(*Arg))
2396 return true;
2397 }
2398 continue;
2399 }
2400 case VisitorJob::TypeLocVisitKind: {
2401 // Perform default visitation for TypeLocs.
2402 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 if (LabelStmt *stmt = LS->getStmt()) {
2409 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2410 TU))) {
2411 return true;
2412 }
2413 }
2414 continue;
2415 }
2416
2417 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2418 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2419 if (VisitNestedNameSpecifierLoc(V->get()))
2420 return true;
2421 continue;
2422 }
2423
2424 case VisitorJob::DeclarationNameInfoVisitKind: {
2425 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2426 ->get()))
2427 return true;
2428 continue;
2429 }
2430 case VisitorJob::MemberRefVisitKind: {
2431 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2432 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2433 return true;
2434 continue;
2435 }
2436 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 if (!S)
2439 continue;
2440
2441 // Update the current cursor.
2442 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2443 if (!IsInRegionOfInterest(Cursor))
2444 continue;
2445 switch (Visitor(Cursor, Parent, ClientData)) {
2446 case CXChildVisit_Break: return true;
2447 case CXChildVisit_Continue: break;
2448 case CXChildVisit_Recurse:
2449 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002450 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 EnqueueWorkList(WL, S);
2452 break;
2453 }
2454 continue;
2455 }
2456 case VisitorJob::MemberExprPartsKind: {
2457 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002459
2460 // Visit the nested-name-specifier
2461 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2462 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2463 return true;
2464
2465 // Visit the declaration name.
2466 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2467 return true;
2468
2469 // Visit the explicitly-specified template arguments, if any.
2470 if (M->hasExplicitTemplateArgs()) {
2471 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2472 *ArgEnd = Arg + M->getNumTemplateArgs();
2473 Arg != ArgEnd; ++Arg) {
2474 if (VisitTemplateArgumentLoc(*Arg))
2475 return true;
2476 }
2477 }
2478 continue;
2479 }
2480 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 // Visit nested-name-specifier, if present.
2483 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2484 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2485 return true;
2486 // Visit declaration name.
2487 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2488 return true;
2489 continue;
2490 }
2491 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 // Visit the nested-name-specifier.
2494 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2495 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2496 return true;
2497 // Visit the declaration name.
2498 if (VisitDeclarationNameInfo(O->getNameInfo()))
2499 return true;
2500 // Visit the overloaded declaration reference.
2501 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2502 return true;
2503 continue;
2504 }
2505 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 NamedDecl *Pack = E->getPack();
2508 if (isa<TemplateTypeParmDecl>(Pack)) {
2509 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2510 E->getPackLoc(), TU)))
2511 return true;
2512
2513 continue;
2514 }
2515
2516 if (isa<TemplateTemplateParmDecl>(Pack)) {
2517 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2518 E->getPackLoc(), TU)))
2519 return true;
2520
2521 continue;
2522 }
2523
2524 // Non-type template parameter packs and function parameter packs are
2525 // treated like DeclRefExpr cursors.
2526 continue;
2527 }
2528
2529 case VisitorJob::LambdaExprPartsKind: {
2530 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2533 CEnd = E->explicit_capture_end();
2534 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002535 // FIXME: Lambda init-captures.
2536 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002538
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2540 C->getLocation(),
2541 TU)))
2542 return true;
2543 }
2544
2545 // Visit parameters and return type, if present.
2546 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2547 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2548 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2549 // Visit the whole type.
2550 if (Visit(TL))
2551 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002552 } else if (FunctionProtoTypeLoc Proto =
2553 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 if (E->hasExplicitParameters()) {
2555 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002556 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2557 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002558 return true;
2559 } else {
2560 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002561 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002562 return true;
2563 }
2564 }
2565 }
2566 break;
2567 }
2568
2569 case VisitorJob::PostChildrenVisitKind:
2570 if (PostChildrenVisitor(Parent, ClientData))
2571 return true;
2572 break;
2573 }
2574 }
2575 return false;
2576}
2577
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002578bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002579 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002580 if (!WorkListFreeList.empty()) {
2581 WL = WorkListFreeList.back();
2582 WL->clear();
2583 WorkListFreeList.pop_back();
2584 }
2585 else {
2586 WL = new VisitorWorkList();
2587 WorkListCache.push_back(WL);
2588 }
2589 EnqueueWorkList(*WL, S);
2590 bool result = RunVisitorWorkList(*WL);
2591 WorkListFreeList.push_back(WL);
2592 return result;
2593}
2594
2595namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002596typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002597RefNamePieces
2598buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2599 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2600 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2602 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2603 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2604
2605 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2606
2607 RefNamePieces Pieces;
2608
2609 if (WantQualifier && QLoc.isValid())
2610 Pieces.push_back(QLoc);
2611
2612 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2613 Pieces.push_back(NI.getLoc());
2614
2615 if (WantTemplateArgs && TemplateArgs)
2616 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2617 TemplateArgs->RAngleLoc));
2618
2619 if (Kind == DeclarationName::CXXOperatorName) {
2620 Pieces.push_back(SourceLocation::getFromRawEncoding(
2621 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2622 Pieces.push_back(SourceLocation::getFromRawEncoding(
2623 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2624 }
2625
2626 if (WantSinglePiece) {
2627 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2628 Pieces.clear();
2629 Pieces.push_back(R);
2630 }
2631
2632 return Pieces;
2633}
2634}
2635
2636//===----------------------------------------------------------------------===//
2637// Misc. API hooks.
2638//===----------------------------------------------------------------------===//
2639
Chad Rosier05c71aa2013-03-27 18:28:23 +00002640static void fatal_error_handler(void *user_data, const std::string& reason,
2641 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 // Write the result out to stderr avoiding errs() because raw_ostreams can
2643 // call report_fatal_error.
2644 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2645 ::abort();
2646}
2647
Chandler Carruth66660742014-06-27 16:37:27 +00002648namespace {
2649struct RegisterFatalErrorHandler {
2650 RegisterFatalErrorHandler() {
2651 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2652 }
2653};
2654}
2655
2656static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2657
Guy Benyei11169dd2012-12-18 14:30:41 +00002658extern "C" {
2659CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2660 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 // We use crash recovery to make some of our APIs more reliable, implicitly
2662 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002663 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2664 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002665
Chandler Carruth66660742014-06-27 16:37:27 +00002666 // Look through the managed static to trigger construction of the managed
2667 // static which registers our fatal error handler. This ensures it is only
2668 // registered once.
2669 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002670
2671 CIndexer *CIdxr = new CIndexer();
2672 if (excludeDeclarationsFromPCH)
2673 CIdxr->setOnlyLocalDecls();
2674 if (displayDiagnostics)
2675 CIdxr->setDisplayDiagnostics();
2676
2677 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2678 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2679 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2680 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2681 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2682 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2683
2684 return CIdxr;
2685}
2686
2687void clang_disposeIndex(CXIndex CIdx) {
2688 if (CIdx)
2689 delete static_cast<CIndexer *>(CIdx);
2690}
2691
2692void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2693 if (CIdx)
2694 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2695}
2696
2697unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2698 if (CIdx)
2699 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2700 return 0;
2701}
2702
2703void clang_toggleCrashRecovery(unsigned isEnabled) {
2704 if (isEnabled)
2705 llvm::CrashRecoveryContext::Enable();
2706 else
2707 llvm::CrashRecoveryContext::Disable();
2708}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002709
Guy Benyei11169dd2012-12-18 14:30:41 +00002710CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2711 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002712 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002713 enum CXErrorCode Result =
2714 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002715 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716 assert((TU && Result == CXError_Success) ||
2717 (!TU && Result != CXError_Success));
2718 return TU;
2719}
2720
2721enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2722 const char *ast_filename,
2723 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002724 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002725 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002726
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002727 if (!CIdx || !ast_filename || !out_TU)
2728 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002729
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002730 LOG_FUNC_SECTION {
2731 *Log << ast_filename;
2732 }
2733
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2735 FileSystemOptions FileSystemOpts;
2736
2737 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002738 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002739 CXXIdx->getOnlyLocalDecls(), None,
2740 /*CaptureDiagnostics=*/true,
2741 /*AllowPCHWithCompilerErrors=*/true,
2742 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002743 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2744 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002745}
2746
2747unsigned clang_defaultEditingTranslationUnitOptions() {
2748 return CXTranslationUnit_PrecompiledPreamble |
2749 CXTranslationUnit_CacheCompletionResults;
2750}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002751
Guy Benyei11169dd2012-12-18 14:30:41 +00002752CXTranslationUnit
2753clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2754 const char *source_filename,
2755 int num_command_line_args,
2756 const char * const *command_line_args,
2757 unsigned num_unsaved_files,
2758 struct CXUnsavedFile *unsaved_files) {
2759 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2760 return clang_parseTranslationUnit(CIdx, source_filename,
2761 command_line_args, num_command_line_args,
2762 unsaved_files, num_unsaved_files,
2763 Options);
2764}
2765
2766struct ParseTranslationUnitInfo {
2767 CXIndex CIdx;
2768 const char *source_filename;
2769 const char *const *command_line_args;
2770 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002771 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002773 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002774 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002775};
2776static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002777 const ParseTranslationUnitInfo *PTUI =
2778 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 CXIndex CIdx = PTUI->CIdx;
2780 const char *source_filename = PTUI->source_filename;
2781 const char * const *command_line_args = PTUI->command_line_args;
2782 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002784 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002785
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002786 // Set up the initial return values.
2787 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002788 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002789
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002790 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002791 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002794 }
2795
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2797
2798 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2799 setThreadBackgroundPriority();
2800
2801 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2802 // FIXME: Add a flag for modules.
2803 TranslationUnitKind TUKind
2804 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002805 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 = options & CXTranslationUnit_CacheCompletionResults;
2807 bool IncludeBriefCommentsInCodeCompletion
2808 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2809 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2810 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2811
2812 // Configure the diagnostics.
2813 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002814 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002815
2816 // Recover resources if we crash before exiting this function.
2817 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2818 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002819 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002820
Ahmed Charlesb8984322014-03-07 20:03:18 +00002821 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2822 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002823
2824 // Recover resources if we crash before exiting this function.
2825 llvm::CrashRecoveryContextCleanupRegistrar<
2826 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2827
Alp Toker9d85b182014-07-07 01:23:14 +00002828 for (auto &UF : PTUI->unsaved_files) {
2829 llvm::MemoryBuffer *MB =
2830 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2831 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 }
2833
Ahmed Charlesb8984322014-03-07 20:03:18 +00002834 std::unique_ptr<std::vector<const char *>> Args(
2835 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002836
2837 // Recover resources if we crash before exiting this method.
2838 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2839 ArgsCleanup(Args.get());
2840
2841 // Since the Clang C library is primarily used by batch tools dealing with
2842 // (often very broken) source code, where spell-checking can have a
2843 // significant negative impact on performance (particularly when
2844 // precompiled headers are involved), we disable it by default.
2845 // Only do this if we haven't found a spell-checking-related argument.
2846 bool FoundSpellCheckingArgument = false;
2847 for (int I = 0; I != num_command_line_args; ++I) {
2848 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2849 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2850 FoundSpellCheckingArgument = true;
2851 break;
2852 }
2853 }
2854 if (!FoundSpellCheckingArgument)
2855 Args->push_back("-fno-spell-checking");
2856
2857 Args->insert(Args->end(), command_line_args,
2858 command_line_args + num_command_line_args);
2859
2860 // The 'source_filename' argument is optional. If the caller does not
2861 // specify it then it is assumed that the source file is specified
2862 // in the actual argument list.
2863 // Put the source file after command_line_args otherwise if '-x' flag is
2864 // present it will be unused.
2865 if (source_filename)
2866 Args->push_back(source_filename);
2867
2868 // Do we need the detailed preprocessing record?
2869 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2870 Args->push_back("-Xclang");
2871 Args->push_back("-detailed-preprocessing-record");
2872 }
2873
2874 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002875 std::unique_ptr<ASTUnit> ErrUnit;
2876 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002877 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002878 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2879 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2880 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2881 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2882 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2883 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002884
2885 if (NumErrors != Diags->getClient()->getNumErrors()) {
2886 // Make sure to check that 'Unit' is non-NULL.
2887 if (CXXIdx->getDisplayDiagnostics())
2888 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2889 }
2890
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002891 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2892 PTUI->result = CXError_ASTReadError;
2893 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002894 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002895 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2896 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002897}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898
2899CXTranslationUnit
2900clang_parseTranslationUnit(CXIndex CIdx,
2901 const char *source_filename,
2902 const char *const *command_line_args,
2903 int num_command_line_args,
2904 struct CXUnsavedFile *unsaved_files,
2905 unsigned num_unsaved_files,
2906 unsigned options) {
2907 CXTranslationUnit TU;
2908 enum CXErrorCode Result = clang_parseTranslationUnit2(
2909 CIdx, source_filename, command_line_args, num_command_line_args,
2910 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002911 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002912 assert((TU && Result == CXError_Success) ||
2913 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002914 return TU;
2915}
2916
2917enum CXErrorCode clang_parseTranslationUnit2(
2918 CXIndex CIdx,
2919 const char *source_filename,
2920 const char *const *command_line_args,
2921 int num_command_line_args,
2922 struct CXUnsavedFile *unsaved_files,
2923 unsigned num_unsaved_files,
2924 unsigned options,
2925 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002926 LOG_FUNC_SECTION {
2927 *Log << source_filename << ": ";
2928 for (int i = 0; i != num_command_line_args; ++i)
2929 *Log << command_line_args[i] << " ";
2930 }
2931
Alp Toker9d85b182014-07-07 01:23:14 +00002932 if (num_unsaved_files && !unsaved_files)
2933 return CXError_InvalidArguments;
2934
Alp Toker5c532982014-07-07 22:42:03 +00002935 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002936 ParseTranslationUnitInfo PTUI = {
2937 CIdx,
2938 source_filename,
2939 command_line_args,
2940 num_command_line_args,
2941 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2942 options,
2943 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002944 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002945 llvm::CrashRecoveryContext CRC;
2946
2947 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2948 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2949 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2950 fprintf(stderr, " 'command_line_args' : [");
2951 for (int i = 0; i != num_command_line_args; ++i) {
2952 if (i)
2953 fprintf(stderr, ", ");
2954 fprintf(stderr, "'%s'", command_line_args[i]);
2955 }
2956 fprintf(stderr, "],\n");
2957 fprintf(stderr, " 'unsaved_files' : [");
2958 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2959 if (i)
2960 fprintf(stderr, ", ");
2961 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2962 unsaved_files[i].Length);
2963 }
2964 fprintf(stderr, "],\n");
2965 fprintf(stderr, " 'options' : %d,\n", options);
2966 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967
2968 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002970 if (CXTranslationUnit *TU = PTUI.out_TU)
2971 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002972 }
Alp Toker5c532982014-07-07 22:42:03 +00002973
2974 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002975}
2976
2977unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2978 return CXSaveTranslationUnit_None;
2979}
2980
2981namespace {
2982
2983struct SaveTranslationUnitInfo {
2984 CXTranslationUnit TU;
2985 const char *FileName;
2986 unsigned options;
2987 CXSaveError result;
2988};
2989
2990}
2991
2992static void clang_saveTranslationUnit_Impl(void *UserData) {
2993 SaveTranslationUnitInfo *STUI =
2994 static_cast<SaveTranslationUnitInfo*>(UserData);
2995
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002996 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002997 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2998 setThreadBackgroundPriority();
2999
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003000 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3002}
3003
3004int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3005 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003006 LOG_FUNC_SECTION {
3007 *Log << TU << ' ' << FileName;
3008 }
3009
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003010 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003011 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003013 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003014
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003015 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3017 if (!CXXUnit->hasSema())
3018 return CXSaveError_InvalidTU;
3019
3020 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3021
3022 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3023 getenv("LIBCLANG_NOTHREADS")) {
3024 clang_saveTranslationUnit_Impl(&STUI);
3025
3026 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3027 PrintLibclangResourceUsage(TU);
3028
3029 return STUI.result;
3030 }
3031
3032 // We have an AST that has invalid nodes due to compiler errors.
3033 // Use a crash recovery thread for protection.
3034
3035 llvm::CrashRecoveryContext CRC;
3036
3037 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3038 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3039 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3040 fprintf(stderr, " 'options' : %d,\n", options);
3041 fprintf(stderr, "}\n");
3042
3043 return CXSaveError_Unknown;
3044
3045 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3046 PrintLibclangResourceUsage(TU);
3047 }
3048
3049 return STUI.result;
3050}
3051
3052void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3053 if (CTUnit) {
3054 // If the translation unit has been marked as unsafe to free, just discard
3055 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3057 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 return;
3059
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003060 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003061 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003062 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3063 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003064 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003065 delete CTUnit;
3066 }
3067}
3068
3069unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3070 return CXReparse_None;
3071}
3072
3073struct ReparseTranslationUnitInfo {
3074 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003075 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003077 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003078};
3079
3080static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003081 const ReparseTranslationUnitInfo *RTUI =
3082 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 unsigned options = RTUI->options;
3085 (void) options;
3086
3087 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003088 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003089 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003090 RTUI->result = CXError_InvalidArguments;
3091 return;
3092 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003093
3094 // Reset the associated diagnostics.
3095 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003096 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003098 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003099 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3100 setThreadBackgroundPriority();
3101
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003102 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003104
3105 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3106 new std::vector<ASTUnit::RemappedFile>());
3107
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 // Recover resources if we crash before exiting this function.
3109 llvm::CrashRecoveryContextCleanupRegistrar<
3110 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003111
3112 for (auto &UF : RTUI->unsaved_files) {
3113 llvm::MemoryBuffer *MB =
3114 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3115 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003118 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003119 RTUI->result = CXError_Success;
3120 else if (isASTReadError(CXXUnit))
3121 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122}
3123
3124int clang_reparseTranslationUnit(CXTranslationUnit TU,
3125 unsigned num_unsaved_files,
3126 struct CXUnsavedFile *unsaved_files,
3127 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003128 LOG_FUNC_SECTION {
3129 *Log << TU;
3130 }
3131
Alp Toker9d85b182014-07-07 01:23:14 +00003132 if (num_unsaved_files && !unsaved_files)
3133 return CXError_InvalidArguments;
3134
Alp Toker5c532982014-07-07 22:42:03 +00003135 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003136 ReparseTranslationUnitInfo RTUI = {
3137 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003138 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003139
3140 if (getenv("LIBCLANG_NOTHREADS")) {
3141 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003142 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 }
3144
3145 llvm::CrashRecoveryContext CRC;
3146
3147 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3148 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003149 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3152 PrintLibclangResourceUsage(TU);
3153
Alp Toker5c532982014-07-07 22:42:03 +00003154 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003155}
3156
3157
3158CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003159 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003160 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003161 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003162 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003163
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003164 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003165 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003166}
3167
3168CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003169 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003170 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003171 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003172 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003173
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003174 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3176}
3177
3178} // end: extern "C"
3179
3180//===----------------------------------------------------------------------===//
3181// CXFile Operations.
3182//===----------------------------------------------------------------------===//
3183
3184extern "C" {
3185CXString clang_getFileName(CXFile SFile) {
3186 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003187 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003188
3189 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003190 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003191}
3192
3193time_t clang_getFileTime(CXFile SFile) {
3194 if (!SFile)
3195 return 0;
3196
3197 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3198 return FEnt->getModificationTime();
3199}
3200
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003201CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003202 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003203 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003204 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003205 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003206
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003207 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
3209 FileManager &FMgr = CXXUnit->getFileManager();
3210 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3211}
3212
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003213unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3214 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003215 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003216 LOG_BAD_TU(TU);
3217 return 0;
3218 }
3219
3220 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return 0;
3222
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003223 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 FileEntry *FEnt = static_cast<FileEntry *>(file);
3225 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3226 .isFileMultipleIncludeGuarded(FEnt);
3227}
3228
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003229int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3230 if (!file || !outID)
3231 return 1;
3232
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003233 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003234 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3235 outID->data[0] = ID.getDevice();
3236 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003237 outID->data[2] = FEnt->getModificationTime();
3238 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003239}
3240
Guy Benyei11169dd2012-12-18 14:30:41 +00003241} // end: extern "C"
3242
3243//===----------------------------------------------------------------------===//
3244// CXCursor Operations.
3245//===----------------------------------------------------------------------===//
3246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003247static const Decl *getDeclFromExpr(const Stmt *E) {
3248 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 return getDeclFromExpr(CE->getSubExpr());
3250
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003251 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003253 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003255 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003257 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 if (PRE->isExplicitProperty())
3259 return PRE->getExplicitProperty();
3260 // It could be messaging both getter and setter as in:
3261 // ++myobj.myprop;
3262 // in which case prefer to associate the setter since it is less obvious
3263 // from inspecting the source that the setter is going to get called.
3264 if (PRE->isMessagingSetter())
3265 return PRE->getImplicitPropertySetter();
3266 return PRE->getImplicitPropertyGetter();
3267 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 if (Expr *Src = OVE->getSourceExpr())
3272 return getDeclFromExpr(Src);
3273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003274 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (!CE->isElidable())
3278 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 return OME->getMethodDecl();
3281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3286 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3289 isa<ParmVarDecl>(SizeOfPack->getPack()))
3290 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003291
3292 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003293}
3294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003295static SourceLocation getLocationFromExpr(const Expr *E) {
3296 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 return getLocationFromExpr(CE->getSubExpr());
3298
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003299 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003301 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003303 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003305 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003307 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003309 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 return PropRef->getLocation();
3311
3312 return E->getLocStart();
3313}
3314
3315extern "C" {
3316
3317unsigned clang_visitChildren(CXCursor parent,
3318 CXCursorVisitor visitor,
3319 CXClientData client_data) {
3320 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3321 /*VisitPreprocessorLast=*/false);
3322 return CursorVis.VisitChildren(parent);
3323}
3324
3325#ifndef __has_feature
3326#define __has_feature(x) 0
3327#endif
3328#if __has_feature(blocks)
3329typedef enum CXChildVisitResult
3330 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3331
3332static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3333 CXClientData client_data) {
3334 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3335 return block(cursor, parent);
3336}
3337#else
3338// If we are compiled with a compiler that doesn't have native blocks support,
3339// define and call the block manually, so the
3340typedef struct _CXChildVisitResult
3341{
3342 void *isa;
3343 int flags;
3344 int reserved;
3345 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3346 CXCursor);
3347} *CXCursorVisitorBlock;
3348
3349static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3350 CXClientData client_data) {
3351 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3352 return block->invoke(block, cursor, parent);
3353}
3354#endif
3355
3356
3357unsigned clang_visitChildrenWithBlock(CXCursor parent,
3358 CXCursorVisitorBlock block) {
3359 return clang_visitChildren(parent, visitWithBlock, block);
3360}
3361
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003365
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003368 if (const ObjCPropertyImplDecl *PropImpl =
3369 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003371 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003372
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003381 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3385 // and returns different names. NamedDecl returns the class name and
3386 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003387 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388
3389 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003390 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003391
3392 SmallString<1024> S;
3393 llvm::raw_svector_ostream os(S);
3394 ND->printName(os);
3395
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397}
3398
3399CXString clang_getCursorSpelling(CXCursor C) {
3400 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003401 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003402
3403 if (clang_isReference(C.kind)) {
3404 switch (C.kind) {
3405 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003406 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003407 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003410 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003411 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003414 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003416 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003419 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003420 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003423 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 assert(Type && "Missing type decl");
3425
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003426 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 getAsString());
3428 }
3429 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003430 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 assert(Template && "Missing template decl");
3432
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
3435
3436 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003437 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 assert(NS && "Missing namespace decl");
3439
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442
3443 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003444 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 assert(Field && "Missing member decl");
3446
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003447 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449
3450 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003451 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 assert(Label && "Missing label");
3453
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003454 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 }
3456
3457 case CXCursor_OverloadedDeclRef: {
3458 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003459 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3460 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003462 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003465 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 OverloadedTemplateStorage *Ovl
3467 = Storage.get<OverloadedTemplateStorage*>();
3468 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003469 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003470 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 }
3472
3473 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003474 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 assert(Var && "Missing variable decl");
3476
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 }
3479
3480 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003481 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 }
3483 }
3484
3485 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003486 const Expr *E = getCursorExpr(C);
3487
3488 if (C.kind == CXCursor_ObjCStringLiteral ||
3489 C.kind == CXCursor_StringLiteral) {
3490 const StringLiteral *SLit;
3491 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3492 SLit = OSL->getString();
3493 } else {
3494 SLit = cast<StringLiteral>(E);
3495 }
3496 SmallString<256> Buf;
3497 llvm::raw_svector_ostream OS(Buf);
3498 SLit->outputString(OS);
3499 return cxstring::createDup(OS.str());
3500 }
3501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 if (D)
3504 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003505 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 }
3507
3508 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003509 const Stmt *S = getCursorStmt(C);
3510 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003511 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003513 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 }
3515
3516 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003517 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 ->getNameStart());
3519
3520 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003521 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 ->getNameStart());
3523
3524 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003525 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003526
3527 if (clang_isDeclaration(C.kind))
3528 return getDeclSpelling(getCursorDecl(C));
3529
3530 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003531 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003532 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 }
3534
3535 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003536 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 }
3539
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003540 if (C.kind == CXCursor_PackedAttr) {
3541 return cxstring::createRef("packed");
3542 }
3543
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003544 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003545}
3546
3547CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3548 unsigned pieceIndex,
3549 unsigned options) {
3550 if (clang_Cursor_isNull(C))
3551 return clang_getNullRange();
3552
3553 ASTContext &Ctx = getCursorContext(C);
3554
3555 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003556 const Stmt *S = getCursorStmt(C);
3557 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 if (pieceIndex > 0)
3559 return clang_getNullRange();
3560 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3561 }
3562
3563 return clang_getNullRange();
3564 }
3565
3566 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003567 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3569 if (pieceIndex >= ME->getNumSelectorLocs())
3570 return clang_getNullRange();
3571 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3572 }
3573 }
3574
3575 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3576 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003577 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3579 if (pieceIndex >= MD->getNumSelectorLocs())
3580 return clang_getNullRange();
3581 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3582 }
3583 }
3584
3585 if (C.kind == CXCursor_ObjCCategoryDecl ||
3586 C.kind == CXCursor_ObjCCategoryImplDecl) {
3587 if (pieceIndex > 0)
3588 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003589 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3591 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3594 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3595 }
3596
3597 if (C.kind == CXCursor_ModuleImportDecl) {
3598 if (pieceIndex > 0)
3599 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const ImportDecl *ImportD =
3601 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3603 if (!Locs.empty())
3604 return cxloc::translateSourceRange(Ctx,
3605 SourceRange(Locs.front(), Locs.back()));
3606 }
3607 return clang_getNullRange();
3608 }
3609
3610 // FIXME: A CXCursor_InclusionDirective should give the location of the
3611 // filename, but we don't keep track of this.
3612
3613 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3614 // but we don't keep track of this.
3615
3616 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3617 // but we don't keep track of this.
3618
3619 // Default handling, give the location of the cursor.
3620
3621 if (pieceIndex > 0)
3622 return clang_getNullRange();
3623
3624 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3625 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3626 return cxloc::translateSourceRange(Ctx, Loc);
3627}
3628
3629CXString clang_getCursorDisplayName(CXCursor C) {
3630 if (!clang_isDeclaration(C.kind))
3631 return clang_getCursorSpelling(C);
3632
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003633 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003636
3637 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003638 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 D = FunTmpl->getTemplatedDecl();
3640
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003641 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 SmallString<64> Str;
3643 llvm::raw_svector_ostream OS(Str);
3644 OS << *Function;
3645 if (Function->getPrimaryTemplate())
3646 OS << "<>";
3647 OS << "(";
3648 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3649 if (I)
3650 OS << ", ";
3651 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3652 }
3653
3654 if (Function->isVariadic()) {
3655 if (Function->getNumParams())
3656 OS << ", ";
3657 OS << "...";
3658 }
3659 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 }
3662
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003663 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 SmallString<64> Str;
3665 llvm::raw_svector_ostream OS(Str);
3666 OS << *ClassTemplate;
3667 OS << "<";
3668 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3669 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3670 if (I)
3671 OS << ", ";
3672
3673 NamedDecl *Param = Params->getParam(I);
3674 if (Param->getIdentifier()) {
3675 OS << Param->getIdentifier()->getName();
3676 continue;
3677 }
3678
3679 // There is no parameter name, which makes this tricky. Try to come up
3680 // with something useful that isn't too long.
3681 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3682 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3683 else if (NonTypeTemplateParmDecl *NTTP
3684 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3685 OS << NTTP->getType().getAsString(Policy);
3686 else
3687 OS << "template<...> class";
3688 }
3689
3690 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003694 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3696 // If the type was explicitly written, use that.
3697 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003698 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003699
Benjamin Kramer9170e912013-02-22 15:46:01 +00003700 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 llvm::raw_svector_ostream OS(Str);
3702 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003703 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 ClassSpec->getTemplateArgs().data(),
3705 ClassSpec->getTemplateArgs().size(),
3706 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003707 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 }
3709
3710 return clang_getCursorSpelling(C);
3711}
3712
3713CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3714 switch (Kind) {
3715 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003843 case CXCursor_ObjCSelfExpr:
3844 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003933 case CXCursor_SEHLeaveStmt:
3934 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003963 case CXCursor_PackedAttr:
3964 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003965 case CXCursor_PureAttr:
3966 return cxstring::createRef("attribute(pure)");
3967 case CXCursor_ConstAttr:
3968 return cxstring::createRef("attribute(const)");
3969 case CXCursor_NoDuplicateAttr:
3970 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003971 case CXCursor_CUDAConstantAttr:
3972 return cxstring::createRef("attribute(constant)");
3973 case CXCursor_CUDADeviceAttr:
3974 return cxstring::createRef("attribute(device)");
3975 case CXCursor_CUDAGlobalAttr:
3976 return cxstring::createRef("attribute(global)");
3977 case CXCursor_CUDAHostAttr:
3978 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004027 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004028 return cxstring::createRef("OMPParallelDirective");
4029 case CXCursor_OMPSimdDirective:
4030 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004031 case CXCursor_OMPForDirective:
4032 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004033 case CXCursor_OMPSectionsDirective:
4034 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004035 case CXCursor_OMPSectionDirective:
4036 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004037 case CXCursor_OMPSingleDirective:
4038 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004039 case CXCursor_OMPMasterDirective:
4040 return cxstring::createRef("OMPMasterDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004041 case CXCursor_OMPParallelForDirective:
4042 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004043 case CXCursor_OMPParallelSectionsDirective:
4044 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004045 case CXCursor_OMPTaskDirective:
4046 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004047 case CXCursor_OMPTaskyieldDirective:
4048 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004049 case CXCursor_OMPBarrierDirective:
4050 return cxstring::createRef("OMPBarrierDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 }
4052
4053 llvm_unreachable("Unhandled CXCursorKind");
4054}
4055
4056struct GetCursorData {
4057 SourceLocation TokenBeginLoc;
4058 bool PointsAtMacroArgExpansion;
4059 bool VisitedObjCPropertyImplDecl;
4060 SourceLocation VisitedDeclaratorDeclStartLoc;
4061 CXCursor &BestCursor;
4062
4063 GetCursorData(SourceManager &SM,
4064 SourceLocation tokenBegin, CXCursor &outputCursor)
4065 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4066 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4067 VisitedObjCPropertyImplDecl = false;
4068 }
4069};
4070
4071static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4072 CXCursor parent,
4073 CXClientData client_data) {
4074 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4075 CXCursor *BestCursor = &Data->BestCursor;
4076
4077 // If we point inside a macro argument we should provide info of what the
4078 // token is so use the actual cursor, don't replace it with a macro expansion
4079 // cursor.
4080 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4081 return CXChildVisit_Recurse;
4082
4083 if (clang_isDeclaration(cursor.kind)) {
4084 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004085 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4087 if (MD->isImplicit())
4088 return CXChildVisit_Break;
4089
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004090 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4092 // Check that when we have multiple @class references in the same line,
4093 // that later ones do not override the previous ones.
4094 // If we have:
4095 // @class Foo, Bar;
4096 // source ranges for both start at '@', so 'Bar' will end up overriding
4097 // 'Foo' even though the cursor location was at 'Foo'.
4098 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4099 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004100 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4102 if (PrevID != ID &&
4103 !PrevID->isThisDeclarationADefinition() &&
4104 !ID->isThisDeclarationADefinition())
4105 return CXChildVisit_Break;
4106 }
4107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004108 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4110 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4111 // Check that when we have multiple declarators in the same line,
4112 // that later ones do not override the previous ones.
4113 // If we have:
4114 // int Foo, Bar;
4115 // source ranges for both start at 'int', so 'Bar' will end up overriding
4116 // 'Foo' even though the cursor location was at 'Foo'.
4117 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4118 return CXChildVisit_Break;
4119 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4120
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004121 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4123 (void)PropImp;
4124 // Check that when we have multiple @synthesize in the same line,
4125 // that later ones do not override the previous ones.
4126 // If we have:
4127 // @synthesize Foo, Bar;
4128 // source ranges for both start at '@', so 'Bar' will end up overriding
4129 // 'Foo' even though the cursor location was at 'Foo'.
4130 if (Data->VisitedObjCPropertyImplDecl)
4131 return CXChildVisit_Break;
4132 Data->VisitedObjCPropertyImplDecl = true;
4133 }
4134 }
4135
4136 if (clang_isExpression(cursor.kind) &&
4137 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004138 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 // Avoid having the cursor of an expression replace the declaration cursor
4140 // when the expression source range overlaps the declaration range.
4141 // This can happen for C++ constructor expressions whose range generally
4142 // include the variable declaration, e.g.:
4143 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4144 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4145 D->getLocation() == Data->TokenBeginLoc)
4146 return CXChildVisit_Break;
4147 }
4148 }
4149
4150 // If our current best cursor is the construction of a temporary object,
4151 // don't replace that cursor with a type reference, because we want
4152 // clang_getCursor() to point at the constructor.
4153 if (clang_isExpression(BestCursor->kind) &&
4154 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4155 cursor.kind == CXCursor_TypeRef) {
4156 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4157 // as having the actual point on the type reference.
4158 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4159 return CXChildVisit_Recurse;
4160 }
4161
4162 *BestCursor = cursor;
4163 return CXChildVisit_Recurse;
4164}
4165
4166CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004167 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004168 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004170 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004171
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004172 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4174
4175 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4176 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4177
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004178 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 CXFile SearchFile;
4180 unsigned SearchLine, SearchColumn;
4181 CXFile ResultFile;
4182 unsigned ResultLine, ResultColumn;
4183 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4184 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4185 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004186
4187 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4188 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004189 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004190 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 SearchFileName = clang_getFileName(SearchFile);
4192 ResultFileName = clang_getFileName(ResultFile);
4193 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4194 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004195 *Log << llvm::format("(%s:%d:%d) = %s",
4196 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4197 clang_getCString(KindSpelling))
4198 << llvm::format("(%s:%d:%d):%s%s",
4199 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4200 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 clang_disposeString(SearchFileName);
4202 clang_disposeString(ResultFileName);
4203 clang_disposeString(KindSpelling);
4204 clang_disposeString(USR);
4205
4206 CXCursor Definition = clang_getCursorDefinition(Result);
4207 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4208 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4209 CXString DefinitionKindSpelling
4210 = clang_getCursorKindSpelling(Definition.kind);
4211 CXFile DefinitionFile;
4212 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004213 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004214 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004216 *Log << llvm::format(" -> %s(%s:%d:%d)",
4217 clang_getCString(DefinitionKindSpelling),
4218 clang_getCString(DefinitionFileName),
4219 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 clang_disposeString(DefinitionFileName);
4221 clang_disposeString(DefinitionKindSpelling);
4222 }
4223 }
4224
4225 return Result;
4226}
4227
4228CXCursor clang_getNullCursor(void) {
4229 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4230}
4231
4232unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004233 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4234 // can't set consistently. For example, when visiting a DeclStmt we will set
4235 // it but we don't set it on the result of clang_getCursorDefinition for
4236 // a reference of the same declaration.
4237 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4238 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4239 // to provide that kind of info.
4240 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004241 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004242 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004243 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004244
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 return X == Y;
4246}
4247
4248unsigned clang_hashCursor(CXCursor C) {
4249 unsigned Index = 0;
4250 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4251 Index = 1;
4252
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004253 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 std::make_pair(C.kind, C.data[Index]));
4255}
4256
4257unsigned clang_isInvalid(enum CXCursorKind K) {
4258 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4259}
4260
4261unsigned clang_isDeclaration(enum CXCursorKind K) {
4262 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4263 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4264}
4265
4266unsigned clang_isReference(enum CXCursorKind K) {
4267 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4268}
4269
4270unsigned clang_isExpression(enum CXCursorKind K) {
4271 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4272}
4273
4274unsigned clang_isStatement(enum CXCursorKind K) {
4275 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4276}
4277
4278unsigned clang_isAttribute(enum CXCursorKind K) {
4279 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4280}
4281
4282unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4283 return K == CXCursor_TranslationUnit;
4284}
4285
4286unsigned clang_isPreprocessing(enum CXCursorKind K) {
4287 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4288}
4289
4290unsigned clang_isUnexposed(enum CXCursorKind K) {
4291 switch (K) {
4292 case CXCursor_UnexposedDecl:
4293 case CXCursor_UnexposedExpr:
4294 case CXCursor_UnexposedStmt:
4295 case CXCursor_UnexposedAttr:
4296 return true;
4297 default:
4298 return false;
4299 }
4300}
4301
4302CXCursorKind clang_getCursorKind(CXCursor C) {
4303 return C.kind;
4304}
4305
4306CXSourceLocation clang_getCursorLocation(CXCursor C) {
4307 if (clang_isReference(C.kind)) {
4308 switch (C.kind) {
4309 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004310 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 = getCursorObjCSuperClassRef(C);
4312 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4313 }
4314
4315 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004316 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 = getCursorObjCProtocolRef(C);
4318 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4319 }
4320
4321 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004322 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 = getCursorObjCClassRef(C);
4324 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4325 }
4326
4327 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004328 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4330 }
4331
4332 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004333 std::pair<const TemplateDecl *, SourceLocation> P =
4334 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4336 }
4337
4338 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004339 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4341 }
4342
4343 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004344 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4346 }
4347
4348 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004349 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4351 }
4352
4353 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004354 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 if (!BaseSpec)
4356 return clang_getNullLocation();
4357
4358 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4359 return cxloc::translateSourceLocation(getCursorContext(C),
4360 TSInfo->getTypeLoc().getBeginLoc());
4361
4362 return cxloc::translateSourceLocation(getCursorContext(C),
4363 BaseSpec->getLocStart());
4364 }
4365
4366 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004367 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4369 }
4370
4371 case CXCursor_OverloadedDeclRef:
4372 return cxloc::translateSourceLocation(getCursorContext(C),
4373 getCursorOverloadedDeclRef(C).second);
4374
4375 default:
4376 // FIXME: Need a way to enumerate all non-reference cases.
4377 llvm_unreachable("Missed a reference kind");
4378 }
4379 }
4380
4381 if (clang_isExpression(C.kind))
4382 return cxloc::translateSourceLocation(getCursorContext(C),
4383 getLocationFromExpr(getCursorExpr(C)));
4384
4385 if (clang_isStatement(C.kind))
4386 return cxloc::translateSourceLocation(getCursorContext(C),
4387 getCursorStmt(C)->getLocStart());
4388
4389 if (C.kind == CXCursor_PreprocessingDirective) {
4390 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4391 return cxloc::translateSourceLocation(getCursorContext(C), L);
4392 }
4393
4394 if (C.kind == CXCursor_MacroExpansion) {
4395 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004396 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 return cxloc::translateSourceLocation(getCursorContext(C), L);
4398 }
4399
4400 if (C.kind == CXCursor_MacroDefinition) {
4401 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4402 return cxloc::translateSourceLocation(getCursorContext(C), L);
4403 }
4404
4405 if (C.kind == CXCursor_InclusionDirective) {
4406 SourceLocation L
4407 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4408 return cxloc::translateSourceLocation(getCursorContext(C), L);
4409 }
4410
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004411 if (clang_isAttribute(C.kind)) {
4412 SourceLocation L
4413 = cxcursor::getCursorAttr(C)->getLocation();
4414 return cxloc::translateSourceLocation(getCursorContext(C), L);
4415 }
4416
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 if (!clang_isDeclaration(C.kind))
4418 return clang_getNullLocation();
4419
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 if (!D)
4422 return clang_getNullLocation();
4423
4424 SourceLocation Loc = D->getLocation();
4425 // FIXME: Multiple variables declared in a single declaration
4426 // currently lack the information needed to correctly determine their
4427 // ranges when accounting for the type-specifier. We use context
4428 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4429 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004430 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 if (!cxcursor::isFirstInDeclGroup(C))
4432 Loc = VD->getLocation();
4433 }
4434
4435 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004436 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 Loc = MD->getSelectorStartLoc();
4438
4439 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4440}
4441
4442} // end extern "C"
4443
4444CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4445 assert(TU);
4446
4447 // Guard against an invalid SourceLocation, or we may assert in one
4448 // of the following calls.
4449 if (SLoc.isInvalid())
4450 return clang_getNullCursor();
4451
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004452 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453
4454 // Translate the given source location to make it point at the beginning of
4455 // the token under the cursor.
4456 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4457 CXXUnit->getASTContext().getLangOpts());
4458
4459 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4460 if (SLoc.isValid()) {
4461 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4462 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4463 /*VisitPreprocessorLast=*/true,
4464 /*VisitIncludedEntities=*/false,
4465 SourceLocation(SLoc));
4466 CursorVis.visitFileRegion();
4467 }
4468
4469 return Result;
4470}
4471
4472static SourceRange getRawCursorExtent(CXCursor C) {
4473 if (clang_isReference(C.kind)) {
4474 switch (C.kind) {
4475 case CXCursor_ObjCSuperClassRef:
4476 return getCursorObjCSuperClassRef(C).second;
4477
4478 case CXCursor_ObjCProtocolRef:
4479 return getCursorObjCProtocolRef(C).second;
4480
4481 case CXCursor_ObjCClassRef:
4482 return getCursorObjCClassRef(C).second;
4483
4484 case CXCursor_TypeRef:
4485 return getCursorTypeRef(C).second;
4486
4487 case CXCursor_TemplateRef:
4488 return getCursorTemplateRef(C).second;
4489
4490 case CXCursor_NamespaceRef:
4491 return getCursorNamespaceRef(C).second;
4492
4493 case CXCursor_MemberRef:
4494 return getCursorMemberRef(C).second;
4495
4496 case CXCursor_CXXBaseSpecifier:
4497 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4498
4499 case CXCursor_LabelRef:
4500 return getCursorLabelRef(C).second;
4501
4502 case CXCursor_OverloadedDeclRef:
4503 return getCursorOverloadedDeclRef(C).second;
4504
4505 case CXCursor_VariableRef:
4506 return getCursorVariableRef(C).second;
4507
4508 default:
4509 // FIXME: Need a way to enumerate all non-reference cases.
4510 llvm_unreachable("Missed a reference kind");
4511 }
4512 }
4513
4514 if (clang_isExpression(C.kind))
4515 return getCursorExpr(C)->getSourceRange();
4516
4517 if (clang_isStatement(C.kind))
4518 return getCursorStmt(C)->getSourceRange();
4519
4520 if (clang_isAttribute(C.kind))
4521 return getCursorAttr(C)->getRange();
4522
4523 if (C.kind == CXCursor_PreprocessingDirective)
4524 return cxcursor::getCursorPreprocessingDirective(C);
4525
4526 if (C.kind == CXCursor_MacroExpansion) {
4527 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004528 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return TU->mapRangeFromPreamble(Range);
4530 }
4531
4532 if (C.kind == CXCursor_MacroDefinition) {
4533 ASTUnit *TU = getCursorASTUnit(C);
4534 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4535 return TU->mapRangeFromPreamble(Range);
4536 }
4537
4538 if (C.kind == CXCursor_InclusionDirective) {
4539 ASTUnit *TU = getCursorASTUnit(C);
4540 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4541 return TU->mapRangeFromPreamble(Range);
4542 }
4543
4544 if (C.kind == CXCursor_TranslationUnit) {
4545 ASTUnit *TU = getCursorASTUnit(C);
4546 FileID MainID = TU->getSourceManager().getMainFileID();
4547 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4548 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4549 return SourceRange(Start, End);
4550 }
4551
4552 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 if (!D)
4555 return SourceRange();
4556
4557 SourceRange R = D->getSourceRange();
4558 // FIXME: Multiple variables declared in a single declaration
4559 // currently lack the information needed to correctly determine their
4560 // ranges when accounting for the type-specifier. We use context
4561 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4562 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004563 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 if (!cxcursor::isFirstInDeclGroup(C))
4565 R.setBegin(VD->getLocation());
4566 }
4567 return R;
4568 }
4569 return SourceRange();
4570}
4571
4572/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4573/// the decl-specifier-seq for declarations.
4574static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4575 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004576 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 if (!D)
4578 return SourceRange();
4579
4580 SourceRange R = D->getSourceRange();
4581
4582 // Adjust the start of the location for declarations preceded by
4583 // declaration specifiers.
4584 SourceLocation StartLoc;
4585 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4586 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4587 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004588 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4590 StartLoc = TI->getTypeLoc().getLocStart();
4591 }
4592
4593 if (StartLoc.isValid() && R.getBegin().isValid() &&
4594 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4595 R.setBegin(StartLoc);
4596
4597 // FIXME: Multiple variables declared in a single declaration
4598 // currently lack the information needed to correctly determine their
4599 // ranges when accounting for the type-specifier. We use context
4600 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4601 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004602 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 if (!cxcursor::isFirstInDeclGroup(C))
4604 R.setBegin(VD->getLocation());
4605 }
4606
4607 return R;
4608 }
4609
4610 return getRawCursorExtent(C);
4611}
4612
4613extern "C" {
4614
4615CXSourceRange clang_getCursorExtent(CXCursor C) {
4616 SourceRange R = getRawCursorExtent(C);
4617 if (R.isInvalid())
4618 return clang_getNullRange();
4619
4620 return cxloc::translateSourceRange(getCursorContext(C), R);
4621}
4622
4623CXCursor clang_getCursorReferenced(CXCursor C) {
4624 if (clang_isInvalid(C.kind))
4625 return clang_getNullCursor();
4626
4627 CXTranslationUnit tu = getCursorTU(C);
4628 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004629 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 if (!D)
4631 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004632 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004634 if (const ObjCPropertyImplDecl *PropImpl =
4635 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4637 return MakeCXCursor(Property, tu);
4638
4639 return C;
4640 }
4641
4642 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004643 const Expr *E = getCursorExpr(C);
4644 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 if (D) {
4646 CXCursor declCursor = MakeCXCursor(D, tu);
4647 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4648 declCursor);
4649 return declCursor;
4650 }
4651
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004652 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return MakeCursorOverloadedDeclRef(Ovl, tu);
4654
4655 return clang_getNullCursor();
4656 }
4657
4658 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004659 const Stmt *S = getCursorStmt(C);
4660 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 if (LabelDecl *label = Goto->getLabel())
4662 if (LabelStmt *labelS = label->getStmt())
4663 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4664
4665 return clang_getNullCursor();
4666 }
4667
4668 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004669 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 return MakeMacroDefinitionCursor(Def, tu);
4671 }
4672
4673 if (!clang_isReference(C.kind))
4674 return clang_getNullCursor();
4675
4676 switch (C.kind) {
4677 case CXCursor_ObjCSuperClassRef:
4678 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4679
4680 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004681 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4682 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 return MakeCXCursor(Def, tu);
4684
4685 return MakeCXCursor(Prot, tu);
4686 }
4687
4688 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004689 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4690 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return MakeCXCursor(Def, tu);
4692
4693 return MakeCXCursor(Class, tu);
4694 }
4695
4696 case CXCursor_TypeRef:
4697 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4698
4699 case CXCursor_TemplateRef:
4700 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4701
4702 case CXCursor_NamespaceRef:
4703 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4704
4705 case CXCursor_MemberRef:
4706 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4707
4708 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004709 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4711 tu ));
4712 }
4713
4714 case CXCursor_LabelRef:
4715 // FIXME: We end up faking the "parent" declaration here because we
4716 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004717 return MakeCXCursor(getCursorLabelRef(C).first,
4718 cxtu::getASTUnit(tu)->getASTContext()
4719 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 tu);
4721
4722 case CXCursor_OverloadedDeclRef:
4723 return C;
4724
4725 case CXCursor_VariableRef:
4726 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4727
4728 default:
4729 // We would prefer to enumerate all non-reference cursor kinds here.
4730 llvm_unreachable("Unhandled reference cursor kind");
4731 }
4732}
4733
4734CXCursor clang_getCursorDefinition(CXCursor C) {
4735 if (clang_isInvalid(C.kind))
4736 return clang_getNullCursor();
4737
4738 CXTranslationUnit TU = getCursorTU(C);
4739
4740 bool WasReference = false;
4741 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4742 C = clang_getCursorReferenced(C);
4743 WasReference = true;
4744 }
4745
4746 if (C.kind == CXCursor_MacroExpansion)
4747 return clang_getCursorReferenced(C);
4748
4749 if (!clang_isDeclaration(C.kind))
4750 return clang_getNullCursor();
4751
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004752 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 if (!D)
4754 return clang_getNullCursor();
4755
4756 switch (D->getKind()) {
4757 // Declaration kinds that don't really separate the notions of
4758 // declaration and definition.
4759 case Decl::Namespace:
4760 case Decl::Typedef:
4761 case Decl::TypeAlias:
4762 case Decl::TypeAliasTemplate:
4763 case Decl::TemplateTypeParm:
4764 case Decl::EnumConstant:
4765 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004766 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case Decl::IndirectField:
4768 case Decl::ObjCIvar:
4769 case Decl::ObjCAtDefsField:
4770 case Decl::ImplicitParam:
4771 case Decl::ParmVar:
4772 case Decl::NonTypeTemplateParm:
4773 case Decl::TemplateTemplateParm:
4774 case Decl::ObjCCategoryImpl:
4775 case Decl::ObjCImplementation:
4776 case Decl::AccessSpec:
4777 case Decl::LinkageSpec:
4778 case Decl::ObjCPropertyImpl:
4779 case Decl::FileScopeAsm:
4780 case Decl::StaticAssert:
4781 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004782 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case Decl::Label: // FIXME: Is this right??
4784 case Decl::ClassScopeFunctionSpecialization:
4785 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004786 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return C;
4788
4789 // Declaration kinds that don't make any sense here, but are
4790 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004791 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 case Decl::TranslationUnit:
4793 break;
4794
4795 // Declaration kinds for which the definition is not resolvable.
4796 case Decl::UnresolvedUsingTypename:
4797 case Decl::UnresolvedUsingValue:
4798 break;
4799
4800 case Decl::UsingDirective:
4801 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4802 TU);
4803
4804 case Decl::NamespaceAlias:
4805 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4806
4807 case Decl::Enum:
4808 case Decl::Record:
4809 case Decl::CXXRecord:
4810 case Decl::ClassTemplateSpecialization:
4811 case Decl::ClassTemplatePartialSpecialization:
4812 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4813 return MakeCXCursor(Def, TU);
4814 return clang_getNullCursor();
4815
4816 case Decl::Function:
4817 case Decl::CXXMethod:
4818 case Decl::CXXConstructor:
4819 case Decl::CXXDestructor:
4820 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004821 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004823 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 return clang_getNullCursor();
4825 }
4826
Larisse Voufo39a1e502013-08-06 01:03:05 +00004827 case Decl::Var:
4828 case Decl::VarTemplateSpecialization:
4829 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 return MakeCXCursor(Def, TU);
4833 return clang_getNullCursor();
4834 }
4835
4836 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004837 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4839 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4840 return clang_getNullCursor();
4841 }
4842
4843 case Decl::ClassTemplate: {
4844 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4845 ->getDefinition())
4846 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4847 TU);
4848 return clang_getNullCursor();
4849 }
4850
Larisse Voufo39a1e502013-08-06 01:03:05 +00004851 case Decl::VarTemplate: {
4852 if (VarDecl *Def =
4853 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4854 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4855 return clang_getNullCursor();
4856 }
4857
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 case Decl::Using:
4859 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4860 D->getLocation(), TU);
4861
4862 case Decl::UsingShadow:
4863 return clang_getCursorDefinition(
4864 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4865 TU));
4866
4867 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 if (Method->isThisDeclarationADefinition())
4870 return C;
4871
4872 // Dig out the method definition in the associated
4873 // @implementation, if we have it.
4874 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4877 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4878 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4879 Method->isInstanceMethod()))
4880 if (Def->isThisDeclarationADefinition())
4881 return MakeCXCursor(Def, TU);
4882
4883 return clang_getNullCursor();
4884 }
4885
4886 case Decl::ObjCCategory:
4887 if (ObjCCategoryImplDecl *Impl
4888 = cast<ObjCCategoryDecl>(D)->getImplementation())
4889 return MakeCXCursor(Impl, TU);
4890 return clang_getNullCursor();
4891
4892 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 return MakeCXCursor(Def, TU);
4895 return clang_getNullCursor();
4896
4897 case Decl::ObjCInterface: {
4898 // There are two notions of a "definition" for an Objective-C
4899 // class: the interface and its implementation. When we resolved a
4900 // reference to an Objective-C class, produce the @interface as
4901 // the definition; when we were provided with the interface,
4902 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004903 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 return MakeCXCursor(Def, TU);
4907 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4908 return MakeCXCursor(Impl, TU);
4909 return clang_getNullCursor();
4910 }
4911
4912 case Decl::ObjCProperty:
4913 // FIXME: We don't really know where to find the
4914 // ObjCPropertyImplDecls that implement this property.
4915 return clang_getNullCursor();
4916
4917 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004918 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004920 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 return MakeCXCursor(Def, TU);
4922
4923 return clang_getNullCursor();
4924
4925 case Decl::Friend:
4926 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4927 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4928 return clang_getNullCursor();
4929
4930 case Decl::FriendTemplate:
4931 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4932 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4933 return clang_getNullCursor();
4934 }
4935
4936 return clang_getNullCursor();
4937}
4938
4939unsigned clang_isCursorDefinition(CXCursor C) {
4940 if (!clang_isDeclaration(C.kind))
4941 return 0;
4942
4943 return clang_getCursorDefinition(C) == C;
4944}
4945
4946CXCursor clang_getCanonicalCursor(CXCursor C) {
4947 if (!clang_isDeclaration(C.kind))
4948 return C;
4949
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004950 if (const Decl *D = getCursorDecl(C)) {
4951 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4953 return MakeCXCursor(CatD, getCursorTU(C));
4954
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4956 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 return MakeCXCursor(IFD, getCursorTU(C));
4958
4959 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4960 }
4961
4962 return C;
4963}
4964
4965int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4966 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4967}
4968
4969unsigned clang_getNumOverloadedDecls(CXCursor C) {
4970 if (C.kind != CXCursor_OverloadedDeclRef)
4971 return 0;
4972
4973 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004974 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 return E->getNumDecls();
4976
4977 if (OverloadedTemplateStorage *S
4978 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4979 return S->size();
4980
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004981 const Decl *D = Storage.get<const Decl *>();
4982 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 return Using->shadow_size();
4984
4985 return 0;
4986}
4987
4988CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4989 if (cursor.kind != CXCursor_OverloadedDeclRef)
4990 return clang_getNullCursor();
4991
4992 if (index >= clang_getNumOverloadedDecls(cursor))
4993 return clang_getNullCursor();
4994
4995 CXTranslationUnit TU = getCursorTU(cursor);
4996 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004997 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 return MakeCXCursor(E->decls_begin()[index], TU);
4999
5000 if (OverloadedTemplateStorage *S
5001 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5002 return MakeCXCursor(S->begin()[index], TU);
5003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 const Decl *D = Storage.get<const Decl *>();
5005 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 // FIXME: This is, unfortunately, linear time.
5007 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5008 std::advance(Pos, index);
5009 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5010 }
5011
5012 return clang_getNullCursor();
5013}
5014
5015void clang_getDefinitionSpellingAndExtent(CXCursor C,
5016 const char **startBuf,
5017 const char **endBuf,
5018 unsigned *startLine,
5019 unsigned *startColumn,
5020 unsigned *endLine,
5021 unsigned *endColumn) {
5022 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005023 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5025
5026 SourceManager &SM = FD->getASTContext().getSourceManager();
5027 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5028 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5029 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5030 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5031 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5032 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5033}
5034
5035
5036CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5037 unsigned PieceIndex) {
5038 RefNamePieces Pieces;
5039
5040 switch (C.kind) {
5041 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005042 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5044 E->getQualifierLoc().getSourceRange());
5045 break;
5046
5047 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005048 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5050 E->getQualifierLoc().getSourceRange(),
5051 E->getOptionalExplicitTemplateArgs());
5052 break;
5053
5054 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005055 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005057 const Expr *Callee = OCE->getCallee();
5058 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 Callee = ICE->getSubExpr();
5060
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005061 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5063 DRE->getQualifierLoc().getSourceRange());
5064 }
5065 break;
5066
5067 default:
5068 break;
5069 }
5070
5071 if (Pieces.empty()) {
5072 if (PieceIndex == 0)
5073 return clang_getCursorExtent(C);
5074 } else if (PieceIndex < Pieces.size()) {
5075 SourceRange R = Pieces[PieceIndex];
5076 if (R.isValid())
5077 return cxloc::translateSourceRange(getCursorContext(C), R);
5078 }
5079
5080 return clang_getNullRange();
5081}
5082
5083void clang_enableStackTraces(void) {
5084 llvm::sys::PrintStackTraceOnErrorSignal();
5085}
5086
5087void clang_executeOnThread(void (*fn)(void*), void *user_data,
5088 unsigned stack_size) {
5089 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5090}
5091
5092} // end: extern "C"
5093
5094//===----------------------------------------------------------------------===//
5095// Token-based Operations.
5096//===----------------------------------------------------------------------===//
5097
5098/* CXToken layout:
5099 * int_data[0]: a CXTokenKind
5100 * int_data[1]: starting token location
5101 * int_data[2]: token length
5102 * int_data[3]: reserved
5103 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5104 * otherwise unused.
5105 */
5106extern "C" {
5107
5108CXTokenKind clang_getTokenKind(CXToken CXTok) {
5109 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5110}
5111
5112CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5113 switch (clang_getTokenKind(CXTok)) {
5114 case CXToken_Identifier:
5115 case CXToken_Keyword:
5116 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005117 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 ->getNameStart());
5119
5120 case CXToken_Literal: {
5121 // We have stashed the starting pointer in the ptr_data field. Use it.
5122 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005123 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 }
5125
5126 case CXToken_Punctuation:
5127 case CXToken_Comment:
5128 break;
5129 }
5130
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005131 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005132 LOG_BAD_TU(TU);
5133 return cxstring::createEmpty();
5134 }
5135
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 // We have to find the starting buffer pointer the hard way, by
5137 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005138 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005140 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005141
5142 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5143 std::pair<FileID, unsigned> LocInfo
5144 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5145 bool Invalid = false;
5146 StringRef Buffer
5147 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5148 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005149 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005150
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005151 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005152}
5153
5154CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005155 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005156 LOG_BAD_TU(TU);
5157 return clang_getNullLocation();
5158 }
5159
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005160 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 if (!CXXUnit)
5162 return clang_getNullLocation();
5163
5164 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5165 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5166}
5167
5168CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005169 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005170 LOG_BAD_TU(TU);
5171 return clang_getNullRange();
5172 }
5173
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005174 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 if (!CXXUnit)
5176 return clang_getNullRange();
5177
5178 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5179 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5180}
5181
5182static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5183 SmallVectorImpl<CXToken> &CXTokens) {
5184 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5185 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005186 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005188 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005189
5190 // Cannot tokenize across files.
5191 if (BeginLocInfo.first != EndLocInfo.first)
5192 return;
5193
5194 // Create a lexer
5195 bool Invalid = false;
5196 StringRef Buffer
5197 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5198 if (Invalid)
5199 return;
5200
5201 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5202 CXXUnit->getASTContext().getLangOpts(),
5203 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5204 Lex.SetCommentRetentionState(true);
5205
5206 // Lex tokens until we hit the end of the range.
5207 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5208 Token Tok;
5209 bool previousWasAt = false;
5210 do {
5211 // Lex the next token
5212 Lex.LexFromRawLexer(Tok);
5213 if (Tok.is(tok::eof))
5214 break;
5215
5216 // Initialize the CXToken.
5217 CXToken CXTok;
5218
5219 // - Common fields
5220 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5221 CXTok.int_data[2] = Tok.getLength();
5222 CXTok.int_data[3] = 0;
5223
5224 // - Kind-specific fields
5225 if (Tok.isLiteral()) {
5226 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005227 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 } else if (Tok.is(tok::raw_identifier)) {
5229 // Lookup the identifier to determine whether we have a keyword.
5230 IdentifierInfo *II
5231 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5232
5233 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5234 CXTok.int_data[0] = CXToken_Keyword;
5235 }
5236 else {
5237 CXTok.int_data[0] = Tok.is(tok::identifier)
5238 ? CXToken_Identifier
5239 : CXToken_Keyword;
5240 }
5241 CXTok.ptr_data = II;
5242 } else if (Tok.is(tok::comment)) {
5243 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005244 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 } else {
5246 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005247 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 }
5249 CXTokens.push_back(CXTok);
5250 previousWasAt = Tok.is(tok::at);
5251 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5252}
5253
5254void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5255 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005256 LOG_FUNC_SECTION {
5257 *Log << TU << ' ' << Range;
5258 }
5259
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005261 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 if (NumTokens)
5263 *NumTokens = 0;
5264
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005265 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005266 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005267 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005268 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005269
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005270 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 if (!CXXUnit || !Tokens || !NumTokens)
5272 return;
5273
5274 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5275
5276 SourceRange R = cxloc::translateCXSourceRange(Range);
5277 if (R.isInvalid())
5278 return;
5279
5280 SmallVector<CXToken, 32> CXTokens;
5281 getTokens(CXXUnit, R, CXTokens);
5282
5283 if (CXTokens.empty())
5284 return;
5285
5286 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5287 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5288 *NumTokens = CXTokens.size();
5289}
5290
5291void clang_disposeTokens(CXTranslationUnit TU,
5292 CXToken *Tokens, unsigned NumTokens) {
5293 free(Tokens);
5294}
5295
5296} // end: extern "C"
5297
5298//===----------------------------------------------------------------------===//
5299// Token annotation APIs.
5300//===----------------------------------------------------------------------===//
5301
Guy Benyei11169dd2012-12-18 14:30:41 +00005302static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5303 CXCursor parent,
5304 CXClientData client_data);
5305static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5306 CXClientData client_data);
5307
5308namespace {
5309class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 CXToken *Tokens;
5311 CXCursor *Cursors;
5312 unsigned NumTokens;
5313 unsigned TokIdx;
5314 unsigned PreprocessingTokIdx;
5315 CursorVisitor AnnotateVis;
5316 SourceManager &SrcMgr;
5317 bool HasContextSensitiveKeywords;
5318
5319 struct PostChildrenInfo {
5320 CXCursor Cursor;
5321 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005322 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 unsigned BeforeChildrenTokenIdx;
5324 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005325 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005326
5327 CXToken &getTok(unsigned Idx) {
5328 assert(Idx < NumTokens);
5329 return Tokens[Idx];
5330 }
5331 const CXToken &getTok(unsigned Idx) const {
5332 assert(Idx < NumTokens);
5333 return Tokens[Idx];
5334 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 bool MoreTokens() const { return TokIdx < NumTokens; }
5336 unsigned NextToken() const { return TokIdx; }
5337 void AdvanceToken() { ++TokIdx; }
5338 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005339 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 }
5341 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005342 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 }
5344 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005345 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 }
5347
5348 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005349 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 SourceRange);
5351
5352public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005353 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005354 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005355 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005357 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 AnnotateTokensVisitor, this,
5359 /*VisitPreprocessorLast=*/true,
5360 /*VisitIncludedEntities=*/false,
5361 RegionOfInterest,
5362 /*VisitDeclsOnly=*/false,
5363 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005364 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 HasContextSensitiveKeywords(false) { }
5366
5367 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5368 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5369 bool postVisitChildren(CXCursor cursor);
5370 void AnnotateTokens();
5371
5372 /// \brief Determine whether the annotator saw any cursors that have
5373 /// context-sensitive keywords.
5374 bool hasContextSensitiveKeywords() const {
5375 return HasContextSensitiveKeywords;
5376 }
5377
5378 ~AnnotateTokensWorker() {
5379 assert(PostChildrenInfos.empty());
5380 }
5381};
5382}
5383
5384void AnnotateTokensWorker::AnnotateTokens() {
5385 // Walk the AST within the region of interest, annotating tokens
5386 // along the way.
5387 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005388}
Guy Benyei11169dd2012-12-18 14:30:41 +00005389
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005390static inline void updateCursorAnnotation(CXCursor &Cursor,
5391 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005392 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005394 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005395}
5396
5397/// \brief It annotates and advances tokens with a cursor until the comparison
5398//// between the cursor location and the source range is the same as
5399/// \arg compResult.
5400///
5401/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5402/// Pass RangeOverlap to annotate tokens inside a range.
5403void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5404 RangeComparisonResult compResult,
5405 SourceRange range) {
5406 while (MoreTokens()) {
5407 const unsigned I = NextToken();
5408 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005409 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5410 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005411
5412 SourceLocation TokLoc = GetTokenLoc(I);
5413 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005414 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 AdvanceToken();
5416 continue;
5417 }
5418 break;
5419 }
5420}
5421
5422/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005423/// \returns true if it advanced beyond all macro tokens, false otherwise.
5424bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 CXCursor updateC,
5426 RangeComparisonResult compResult,
5427 SourceRange range) {
5428 assert(MoreTokens());
5429 assert(isFunctionMacroToken(NextToken()) &&
5430 "Should be called only for macro arg tokens");
5431
5432 // This works differently than annotateAndAdvanceTokens; because expanded
5433 // macro arguments can have arbitrary translation-unit source order, we do not
5434 // advance the token index one by one until a token fails the range test.
5435 // We only advance once past all of the macro arg tokens if all of them
5436 // pass the range test. If one of them fails we keep the token index pointing
5437 // at the start of the macro arg tokens so that the failing token will be
5438 // annotated by a subsequent annotation try.
5439
5440 bool atLeastOneCompFail = false;
5441
5442 unsigned I = NextToken();
5443 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5444 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5445 if (TokLoc.isFileID())
5446 continue; // not macro arg token, it's parens or comma.
5447 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5448 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5449 Cursors[I] = updateC;
5450 } else
5451 atLeastOneCompFail = true;
5452 }
5453
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005454 if (atLeastOneCompFail)
5455 return false;
5456
5457 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5458 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005459}
5460
5461enum CXChildVisitResult
5462AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 SourceRange cursorRange = getRawCursorExtent(cursor);
5464 if (cursorRange.isInvalid())
5465 return CXChildVisit_Recurse;
5466
5467 if (!HasContextSensitiveKeywords) {
5468 // Objective-C properties can have context-sensitive keywords.
5469 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005470 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5472 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5473 }
5474 // Objective-C methods can have context-sensitive keywords.
5475 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5476 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005477 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5479 if (Method->getObjCDeclQualifier())
5480 HasContextSensitiveKeywords = true;
5481 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005482 for (const auto *P : Method->params()) {
5483 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 HasContextSensitiveKeywords = true;
5485 break;
5486 }
5487 }
5488 }
5489 }
5490 }
5491 // C++ methods can have context-sensitive keywords.
5492 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005493 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5495 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5496 HasContextSensitiveKeywords = true;
5497 }
5498 }
5499 // C++ classes can have context-sensitive keywords.
5500 else if (cursor.kind == CXCursor_StructDecl ||
5501 cursor.kind == CXCursor_ClassDecl ||
5502 cursor.kind == CXCursor_ClassTemplate ||
5503 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005504 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 if (D->hasAttr<FinalAttr>())
5506 HasContextSensitiveKeywords = true;
5507 }
5508 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005509
5510 // Don't override a property annotation with its getter/setter method.
5511 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5512 parent.kind == CXCursor_ObjCPropertyDecl)
5513 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005514
5515 if (clang_isPreprocessing(cursor.kind)) {
5516 // Items in the preprocessing record are kept separate from items in
5517 // declarations, so we keep a separate token index.
5518 unsigned SavedTokIdx = TokIdx;
5519 TokIdx = PreprocessingTokIdx;
5520
5521 // Skip tokens up until we catch up to the beginning of the preprocessing
5522 // entry.
5523 while (MoreTokens()) {
5524 const unsigned I = NextToken();
5525 SourceLocation TokLoc = GetTokenLoc(I);
5526 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5527 case RangeBefore:
5528 AdvanceToken();
5529 continue;
5530 case RangeAfter:
5531 case RangeOverlap:
5532 break;
5533 }
5534 break;
5535 }
5536
5537 // Look at all of the tokens within this range.
5538 while (MoreTokens()) {
5539 const unsigned I = NextToken();
5540 SourceLocation TokLoc = GetTokenLoc(I);
5541 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5542 case RangeBefore:
5543 llvm_unreachable("Infeasible");
5544 case RangeAfter:
5545 break;
5546 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005547 // For macro expansions, just note where the beginning of the macro
5548 // expansion occurs.
5549 if (cursor.kind == CXCursor_MacroExpansion) {
5550 if (TokLoc == cursorRange.getBegin())
5551 Cursors[I] = cursor;
5552 AdvanceToken();
5553 break;
5554 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005555 // We may have already annotated macro names inside macro definitions.
5556 if (Cursors[I].kind != CXCursor_MacroExpansion)
5557 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 continue;
5560 }
5561 break;
5562 }
5563
5564 // Save the preprocessing token index; restore the non-preprocessing
5565 // token index.
5566 PreprocessingTokIdx = TokIdx;
5567 TokIdx = SavedTokIdx;
5568 return CXChildVisit_Recurse;
5569 }
5570
5571 if (cursorRange.isInvalid())
5572 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005573
5574 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005575 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 const enum CXCursorKind K = clang_getCursorKind(parent);
5577 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005578 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5579 // Attributes are annotated out-of-order, skip tokens until we reach it.
5580 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 ? clang_getNullCursor() : parent;
5582
5583 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5584
5585 // Avoid having the cursor of an expression "overwrite" the annotation of the
5586 // variable declaration that it belongs to.
5587 // This can happen for C++ constructor expressions whose range generally
5588 // include the variable declaration, e.g.:
5589 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005590 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005591 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005592 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 const unsigned I = NextToken();
5594 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5595 E->getLocStart() == D->getLocation() &&
5596 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005597 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 AdvanceToken();
5599 }
5600 }
5601 }
5602
5603 // Before recursing into the children keep some state that we are going
5604 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5605 // extra work after the child nodes are visited.
5606 // Note that we don't call VisitChildren here to avoid traversing statements
5607 // code-recursively which can blow the stack.
5608
5609 PostChildrenInfo Info;
5610 Info.Cursor = cursor;
5611 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005612 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 Info.BeforeChildrenTokenIdx = NextToken();
5614 PostChildrenInfos.push_back(Info);
5615
5616 return CXChildVisit_Recurse;
5617}
5618
5619bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5620 if (PostChildrenInfos.empty())
5621 return false;
5622 const PostChildrenInfo &Info = PostChildrenInfos.back();
5623 if (!clang_equalCursors(Info.Cursor, cursor))
5624 return false;
5625
5626 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5627 const unsigned AfterChildren = NextToken();
5628 SourceRange cursorRange = Info.CursorRange;
5629
5630 // Scan the tokens that are at the end of the cursor, but are not captured
5631 // but the child cursors.
5632 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5633
5634 // Scan the tokens that are at the beginning of the cursor, but are not
5635 // capture by the child cursors.
5636 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5637 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5638 break;
5639
5640 Cursors[I] = cursor;
5641 }
5642
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005643 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5644 // encountered the attribute cursor.
5645 if (clang_isAttribute(cursor.kind))
5646 TokIdx = Info.BeforeReachingCursorIdx;
5647
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 PostChildrenInfos.pop_back();
5649 return false;
5650}
5651
5652static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5653 CXCursor parent,
5654 CXClientData client_data) {
5655 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5656}
5657
5658static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5659 CXClientData client_data) {
5660 return static_cast<AnnotateTokensWorker*>(client_data)->
5661 postVisitChildren(cursor);
5662}
5663
5664namespace {
5665
5666/// \brief Uses the macro expansions in the preprocessing record to find
5667/// and mark tokens that are macro arguments. This info is used by the
5668/// AnnotateTokensWorker.
5669class MarkMacroArgTokensVisitor {
5670 SourceManager &SM;
5671 CXToken *Tokens;
5672 unsigned NumTokens;
5673 unsigned CurIdx;
5674
5675public:
5676 MarkMacroArgTokensVisitor(SourceManager &SM,
5677 CXToken *tokens, unsigned numTokens)
5678 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5679
5680 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5681 if (cursor.kind != CXCursor_MacroExpansion)
5682 return CXChildVisit_Continue;
5683
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005684 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 if (macroRange.getBegin() == macroRange.getEnd())
5686 return CXChildVisit_Continue; // it's not a function macro.
5687
5688 for (; CurIdx < NumTokens; ++CurIdx) {
5689 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5690 macroRange.getBegin()))
5691 break;
5692 }
5693
5694 if (CurIdx == NumTokens)
5695 return CXChildVisit_Break;
5696
5697 for (; CurIdx < NumTokens; ++CurIdx) {
5698 SourceLocation tokLoc = getTokenLoc(CurIdx);
5699 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5700 break;
5701
5702 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5703 }
5704
5705 if (CurIdx == NumTokens)
5706 return CXChildVisit_Break;
5707
5708 return CXChildVisit_Continue;
5709 }
5710
5711private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005712 CXToken &getTok(unsigned Idx) {
5713 assert(Idx < NumTokens);
5714 return Tokens[Idx];
5715 }
5716 const CXToken &getTok(unsigned Idx) const {
5717 assert(Idx < NumTokens);
5718 return Tokens[Idx];
5719 }
5720
Guy Benyei11169dd2012-12-18 14:30:41 +00005721 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005722 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 }
5724
5725 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5726 // The third field is reserved and currently not used. Use it here
5727 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005728 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 }
5730};
5731
5732} // end anonymous namespace
5733
5734static CXChildVisitResult
5735MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5736 CXClientData client_data) {
5737 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5738 parent);
5739}
5740
5741namespace {
5742 struct clang_annotateTokens_Data {
5743 CXTranslationUnit TU;
5744 ASTUnit *CXXUnit;
5745 CXToken *Tokens;
5746 unsigned NumTokens;
5747 CXCursor *Cursors;
5748 };
5749}
5750
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751/// \brief Used by \c annotatePreprocessorTokens.
5752/// \returns true if lexing was finished, false otherwise.
5753static bool lexNext(Lexer &Lex, Token &Tok,
5754 unsigned &NextIdx, unsigned NumTokens) {
5755 if (NextIdx >= NumTokens)
5756 return true;
5757
5758 ++NextIdx;
5759 Lex.LexFromRawLexer(Tok);
5760 if (Tok.is(tok::eof))
5761 return true;
5762
5763 return false;
5764}
5765
Guy Benyei11169dd2012-12-18 14:30:41 +00005766static void annotatePreprocessorTokens(CXTranslationUnit TU,
5767 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005768 CXCursor *Cursors,
5769 CXToken *Tokens,
5770 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005771 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005772
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005773 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5775 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005776 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005777 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005778 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005779
5780 if (BeginLocInfo.first != EndLocInfo.first)
5781 return;
5782
5783 StringRef Buffer;
5784 bool Invalid = false;
5785 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5786 if (Buffer.empty() || Invalid)
5787 return;
5788
5789 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5790 CXXUnit->getASTContext().getLangOpts(),
5791 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5792 Buffer.end());
5793 Lex.SetCommentRetentionState(true);
5794
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005795 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 // Lex tokens in raw mode until we hit the end of the range, to avoid
5797 // entering #includes or expanding macros.
5798 while (true) {
5799 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5801 break;
5802 unsigned TokIdx = NextIdx-1;
5803 assert(Tok.getLocation() ==
5804 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005805
5806 reprocess:
5807 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005808 // We have found a preprocessing directive. Annotate the tokens
5809 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 //
5811 // FIXME: Some simple tests here could identify macro definitions and
5812 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005813
5814 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005815 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5816 break;
5817
Craig Topper69186e72014-06-08 08:38:04 +00005818 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005819 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005820 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5821 break;
5822
5823 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005824 IdentifierInfo &II =
5825 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005826 SourceLocation MappedTokLoc =
5827 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5828 MI = getMacroInfo(II, MappedTokLoc, TU);
5829 }
5830 }
5831
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005832 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005834 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5835 finished = true;
5836 break;
5837 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005838 // If we are in a macro definition, check if the token was ever a
5839 // macro name and annotate it if that's the case.
5840 if (MI) {
5841 SourceLocation SaveLoc = Tok.getLocation();
5842 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5843 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5844 Tok.setLocation(SaveLoc);
5845 if (MacroDef)
5846 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5847 Tok.getLocation(), TU);
5848 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 } while (!Tok.isAtStartOfLine());
5850
5851 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5852 assert(TokIdx <= LastIdx);
5853 SourceLocation EndLoc =
5854 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5855 CXCursor Cursor =
5856 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5857
5858 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005859 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005860
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005861 if (finished)
5862 break;
5863 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005864 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 }
5866}
5867
5868// This gets run a separate thread to avoid stack blowout.
5869static void clang_annotateTokensImpl(void *UserData) {
5870 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5871 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5872 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5873 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5874 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5875
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005876 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5878 setThreadBackgroundPriority();
5879
5880 // Determine the region of interest, which contains all of the tokens.
5881 SourceRange RegionOfInterest;
5882 RegionOfInterest.setBegin(
5883 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5884 RegionOfInterest.setEnd(
5885 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5886 Tokens[NumTokens-1])));
5887
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 // Relex the tokens within the source range to look for preprocessing
5889 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005890 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005891
5892 // If begin location points inside a macro argument, set it to the expansion
5893 // location so we can have the full context when annotating semantically.
5894 {
5895 SourceManager &SM = CXXUnit->getSourceManager();
5896 SourceLocation Loc =
5897 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5898 if (Loc.isMacroID())
5899 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5900 }
5901
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5903 // Search and mark tokens that are macro argument expansions.
5904 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5905 Tokens, NumTokens);
5906 CursorVisitor MacroArgMarker(TU,
5907 MarkMacroArgTokensVisitorDelegate, &Visitor,
5908 /*VisitPreprocessorLast=*/true,
5909 /*VisitIncludedEntities=*/false,
5910 RegionOfInterest);
5911 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5912 }
5913
5914 // Annotate all of the source locations in the region of interest that map to
5915 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005916 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005917
5918 // FIXME: We use a ridiculous stack size here because the data-recursion
5919 // algorithm uses a large stack frame than the non-data recursive version,
5920 // and AnnotationTokensWorker currently transforms the data-recursion
5921 // algorithm back into a traditional recursion by explicitly calling
5922 // VisitChildren(). We will need to remove this explicit recursive call.
5923 W.AnnotateTokens();
5924
5925 // If we ran into any entities that involve context-sensitive keywords,
5926 // take another pass through the tokens to mark them as such.
5927 if (W.hasContextSensitiveKeywords()) {
5928 for (unsigned I = 0; I != NumTokens; ++I) {
5929 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5930 continue;
5931
5932 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5933 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005934 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5936 if (Property->getPropertyAttributesAsWritten() != 0 &&
5937 llvm::StringSwitch<bool>(II->getName())
5938 .Case("readonly", true)
5939 .Case("assign", true)
5940 .Case("unsafe_unretained", true)
5941 .Case("readwrite", true)
5942 .Case("retain", true)
5943 .Case("copy", true)
5944 .Case("nonatomic", true)
5945 .Case("atomic", true)
5946 .Case("getter", true)
5947 .Case("setter", true)
5948 .Case("strong", true)
5949 .Case("weak", true)
5950 .Default(false))
5951 Tokens[I].int_data[0] = CXToken_Keyword;
5952 }
5953 continue;
5954 }
5955
5956 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5957 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5958 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5959 if (llvm::StringSwitch<bool>(II->getName())
5960 .Case("in", true)
5961 .Case("out", true)
5962 .Case("inout", true)
5963 .Case("oneway", true)
5964 .Case("bycopy", true)
5965 .Case("byref", true)
5966 .Default(false))
5967 Tokens[I].int_data[0] = CXToken_Keyword;
5968 continue;
5969 }
5970
5971 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5972 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5973 Tokens[I].int_data[0] = CXToken_Keyword;
5974 continue;
5975 }
5976 }
5977 }
5978}
5979
5980extern "C" {
5981
5982void clang_annotateTokens(CXTranslationUnit TU,
5983 CXToken *Tokens, unsigned NumTokens,
5984 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005985 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005986 LOG_BAD_TU(TU);
5987 return;
5988 }
5989 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005990 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005991 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005992 }
5993
5994 LOG_FUNC_SECTION {
5995 *Log << TU << ' ';
5996 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5997 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5998 *Log << clang_getRange(bloc, eloc);
5999 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006000
6001 // Any token we don't specifically annotate will have a NULL cursor.
6002 CXCursor C = clang_getNullCursor();
6003 for (unsigned I = 0; I != NumTokens; ++I)
6004 Cursors[I] = C;
6005
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006006 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 if (!CXXUnit)
6008 return;
6009
6010 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6011
6012 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6013 llvm::CrashRecoveryContext CRC;
6014 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6015 GetSafetyThreadStackSize() * 2)) {
6016 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6017 }
6018}
6019
6020} // end: extern "C"
6021
6022//===----------------------------------------------------------------------===//
6023// Operations for querying linkage of a cursor.
6024//===----------------------------------------------------------------------===//
6025
6026extern "C" {
6027CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6028 if (!clang_isDeclaration(cursor.kind))
6029 return CXLinkage_Invalid;
6030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006031 const Decl *D = cxcursor::getCursorDecl(cursor);
6032 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006033 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006034 case NoLinkage:
6035 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 case InternalLinkage: return CXLinkage_Internal;
6037 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6038 case ExternalLinkage: return CXLinkage_External;
6039 };
6040
6041 return CXLinkage_Invalid;
6042}
6043} // end: extern "C"
6044
6045//===----------------------------------------------------------------------===//
6046// Operations for querying language of a cursor.
6047//===----------------------------------------------------------------------===//
6048
6049static CXLanguageKind getDeclLanguage(const Decl *D) {
6050 if (!D)
6051 return CXLanguage_C;
6052
6053 switch (D->getKind()) {
6054 default:
6055 break;
6056 case Decl::ImplicitParam:
6057 case Decl::ObjCAtDefsField:
6058 case Decl::ObjCCategory:
6059 case Decl::ObjCCategoryImpl:
6060 case Decl::ObjCCompatibleAlias:
6061 case Decl::ObjCImplementation:
6062 case Decl::ObjCInterface:
6063 case Decl::ObjCIvar:
6064 case Decl::ObjCMethod:
6065 case Decl::ObjCProperty:
6066 case Decl::ObjCPropertyImpl:
6067 case Decl::ObjCProtocol:
6068 return CXLanguage_ObjC;
6069 case Decl::CXXConstructor:
6070 case Decl::CXXConversion:
6071 case Decl::CXXDestructor:
6072 case Decl::CXXMethod:
6073 case Decl::CXXRecord:
6074 case Decl::ClassTemplate:
6075 case Decl::ClassTemplatePartialSpecialization:
6076 case Decl::ClassTemplateSpecialization:
6077 case Decl::Friend:
6078 case Decl::FriendTemplate:
6079 case Decl::FunctionTemplate:
6080 case Decl::LinkageSpec:
6081 case Decl::Namespace:
6082 case Decl::NamespaceAlias:
6083 case Decl::NonTypeTemplateParm:
6084 case Decl::StaticAssert:
6085 case Decl::TemplateTemplateParm:
6086 case Decl::TemplateTypeParm:
6087 case Decl::UnresolvedUsingTypename:
6088 case Decl::UnresolvedUsingValue:
6089 case Decl::Using:
6090 case Decl::UsingDirective:
6091 case Decl::UsingShadow:
6092 return CXLanguage_CPlusPlus;
6093 }
6094
6095 return CXLanguage_C;
6096}
6097
6098extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006099
6100static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6101 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6102 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006103
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104 switch (D->getAvailability()) {
6105 case AR_Available:
6106 case AR_NotYetIntroduced:
6107 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006108 return getCursorAvailabilityForDecl(
6109 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110 return CXAvailability_Available;
6111
6112 case AR_Deprecated:
6113 return CXAvailability_Deprecated;
6114
6115 case AR_Unavailable:
6116 return CXAvailability_NotAvailable;
6117 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006118
6119 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006120}
6121
Guy Benyei11169dd2012-12-18 14:30:41 +00006122enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6123 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006124 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6125 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006126
6127 return CXAvailability_Available;
6128}
6129
6130static CXVersion convertVersion(VersionTuple In) {
6131 CXVersion Out = { -1, -1, -1 };
6132 if (In.empty())
6133 return Out;
6134
6135 Out.Major = In.getMajor();
6136
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006137 Optional<unsigned> Minor = In.getMinor();
6138 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 Out.Minor = *Minor;
6140 else
6141 return Out;
6142
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006143 Optional<unsigned> Subminor = In.getSubminor();
6144 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 Out.Subminor = *Subminor;
6146
6147 return Out;
6148}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006149
6150static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6151 int *always_deprecated,
6152 CXString *deprecated_message,
6153 int *always_unavailable,
6154 CXString *unavailable_message,
6155 CXPlatformAvailability *availability,
6156 int availability_size) {
6157 bool HadAvailAttr = false;
6158 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006159 for (auto A : D->attrs()) {
6160 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006161 HadAvailAttr = true;
6162 if (always_deprecated)
6163 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006164 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006165 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006166 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006167 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006168 continue;
6169 }
6170
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006171 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006172 HadAvailAttr = true;
6173 if (always_unavailable)
6174 *always_unavailable = 1;
6175 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006176 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006177 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6178 }
6179 continue;
6180 }
6181
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006182 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006183 HadAvailAttr = true;
6184 if (N < availability_size) {
6185 availability[N].Platform
6186 = cxstring::createDup(Avail->getPlatform()->getName());
6187 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6188 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6189 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6190 availability[N].Unavailable = Avail->getUnavailable();
6191 availability[N].Message = cxstring::createDup(Avail->getMessage());
6192 }
6193 ++N;
6194 }
6195 }
6196
6197 if (!HadAvailAttr)
6198 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6199 return getCursorPlatformAvailabilityForDecl(
6200 cast<Decl>(EnumConst->getDeclContext()),
6201 always_deprecated,
6202 deprecated_message,
6203 always_unavailable,
6204 unavailable_message,
6205 availability,
6206 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006207
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006208 return N;
6209}
6210
Guy Benyei11169dd2012-12-18 14:30:41 +00006211int clang_getCursorPlatformAvailability(CXCursor cursor,
6212 int *always_deprecated,
6213 CXString *deprecated_message,
6214 int *always_unavailable,
6215 CXString *unavailable_message,
6216 CXPlatformAvailability *availability,
6217 int availability_size) {
6218 if (always_deprecated)
6219 *always_deprecated = 0;
6220 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006221 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 if (always_unavailable)
6223 *always_unavailable = 0;
6224 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006225 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006226
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 if (!clang_isDeclaration(cursor.kind))
6228 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006229
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006230 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 if (!D)
6232 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006233
6234 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6235 deprecated_message,
6236 always_unavailable,
6237 unavailable_message,
6238 availability,
6239 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006240}
6241
6242void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6243 clang_disposeString(availability->Platform);
6244 clang_disposeString(availability->Message);
6245}
6246
6247CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6248 if (clang_isDeclaration(cursor.kind))
6249 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6250
6251 return CXLanguage_Invalid;
6252}
6253
6254 /// \brief If the given cursor is the "templated" declaration
6255 /// descibing a class or function template, return the class or
6256 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006257static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006259 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006260
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006261 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6263 return FunTmpl;
6264
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006265 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006266 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6267 return ClassTmpl;
6268
6269 return D;
6270}
6271
6272CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6273 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006274 if (const Decl *D = getCursorDecl(cursor)) {
6275 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 if (!DC)
6277 return clang_getNullCursor();
6278
6279 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6280 getCursorTU(cursor));
6281 }
6282 }
6283
6284 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006285 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006286 return MakeCXCursor(D, getCursorTU(cursor));
6287 }
6288
6289 return clang_getNullCursor();
6290}
6291
6292CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6293 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006294 if (const Decl *D = getCursorDecl(cursor)) {
6295 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006296 if (!DC)
6297 return clang_getNullCursor();
6298
6299 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6300 getCursorTU(cursor));
6301 }
6302 }
6303
6304 // FIXME: Note that we can't easily compute the lexical context of a
6305 // statement or expression, so we return nothing.
6306 return clang_getNullCursor();
6307}
6308
6309CXFile clang_getIncludedFile(CXCursor cursor) {
6310 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006311 return nullptr;
6312
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006313 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006314 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006315}
6316
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006317unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6318 if (C.kind != CXCursor_ObjCPropertyDecl)
6319 return CXObjCPropertyAttr_noattr;
6320
6321 unsigned Result = CXObjCPropertyAttr_noattr;
6322 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6323 ObjCPropertyDecl::PropertyAttributeKind Attr =
6324 PD->getPropertyAttributesAsWritten();
6325
6326#define SET_CXOBJCPROP_ATTR(A) \
6327 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6328 Result |= CXObjCPropertyAttr_##A
6329 SET_CXOBJCPROP_ATTR(readonly);
6330 SET_CXOBJCPROP_ATTR(getter);
6331 SET_CXOBJCPROP_ATTR(assign);
6332 SET_CXOBJCPROP_ATTR(readwrite);
6333 SET_CXOBJCPROP_ATTR(retain);
6334 SET_CXOBJCPROP_ATTR(copy);
6335 SET_CXOBJCPROP_ATTR(nonatomic);
6336 SET_CXOBJCPROP_ATTR(setter);
6337 SET_CXOBJCPROP_ATTR(atomic);
6338 SET_CXOBJCPROP_ATTR(weak);
6339 SET_CXOBJCPROP_ATTR(strong);
6340 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6341#undef SET_CXOBJCPROP_ATTR
6342
6343 return Result;
6344}
6345
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006346unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6347 if (!clang_isDeclaration(C.kind))
6348 return CXObjCDeclQualifier_None;
6349
6350 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6351 const Decl *D = getCursorDecl(C);
6352 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6353 QT = MD->getObjCDeclQualifier();
6354 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6355 QT = PD->getObjCDeclQualifier();
6356 if (QT == Decl::OBJC_TQ_None)
6357 return CXObjCDeclQualifier_None;
6358
6359 unsigned Result = CXObjCDeclQualifier_None;
6360 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6361 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6362 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6363 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6364 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6365 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6366
6367 return Result;
6368}
6369
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006370unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6371 if (!clang_isDeclaration(C.kind))
6372 return 0;
6373
6374 const Decl *D = getCursorDecl(C);
6375 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6376 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6377 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6378 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6379
6380 return 0;
6381}
6382
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006383unsigned clang_Cursor_isVariadic(CXCursor C) {
6384 if (!clang_isDeclaration(C.kind))
6385 return 0;
6386
6387 const Decl *D = getCursorDecl(C);
6388 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6389 return FD->isVariadic();
6390 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6391 return MD->isVariadic();
6392
6393 return 0;
6394}
6395
Guy Benyei11169dd2012-12-18 14:30:41 +00006396CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6397 if (!clang_isDeclaration(C.kind))
6398 return clang_getNullRange();
6399
6400 const Decl *D = getCursorDecl(C);
6401 ASTContext &Context = getCursorContext(C);
6402 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6403 if (!RC)
6404 return clang_getNullRange();
6405
6406 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6407}
6408
6409CXString clang_Cursor_getRawCommentText(CXCursor C) {
6410 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006411 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006412
6413 const Decl *D = getCursorDecl(C);
6414 ASTContext &Context = getCursorContext(C);
6415 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6416 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6417 StringRef();
6418
6419 // Don't duplicate the string because RawText points directly into source
6420 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006421 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006422}
6423
6424CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6425 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006426 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006427
6428 const Decl *D = getCursorDecl(C);
6429 const ASTContext &Context = getCursorContext(C);
6430 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6431
6432 if (RC) {
6433 StringRef BriefText = RC->getBriefText(Context);
6434
6435 // Don't duplicate the string because RawComment ensures that this memory
6436 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006437 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 }
6439
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006440 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006441}
6442
Guy Benyei11169dd2012-12-18 14:30:41 +00006443CXModule clang_Cursor_getModule(CXCursor C) {
6444 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006445 if (const ImportDecl *ImportD =
6446 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 return ImportD->getImportedModule();
6448 }
6449
Craig Topper69186e72014-06-08 08:38:04 +00006450 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006451}
6452
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006453CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6454 if (isNotUsableTU(TU)) {
6455 LOG_BAD_TU(TU);
6456 return nullptr;
6457 }
6458 if (!File)
6459 return nullptr;
6460 FileEntry *FE = static_cast<FileEntry *>(File);
6461
6462 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6463 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6464 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6465
6466 if (Module *Mod = Header.getModule()) {
6467 if (Header.getRole() != ModuleMap::ExcludedHeader)
6468 return Mod;
6469 }
6470 return nullptr;
6471}
6472
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006473CXFile clang_Module_getASTFile(CXModule CXMod) {
6474 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006475 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006476 Module *Mod = static_cast<Module*>(CXMod);
6477 return const_cast<FileEntry *>(Mod->getASTFile());
6478}
6479
Guy Benyei11169dd2012-12-18 14:30:41 +00006480CXModule clang_Module_getParent(CXModule CXMod) {
6481 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006482 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006483 Module *Mod = static_cast<Module*>(CXMod);
6484 return Mod->Parent;
6485}
6486
6487CXString clang_Module_getName(CXModule CXMod) {
6488 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006489 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006490 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006491 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006492}
6493
6494CXString clang_Module_getFullName(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->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006499}
6500
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006501int clang_Module_isSystem(CXModule CXMod) {
6502 if (!CXMod)
6503 return 0;
6504 Module *Mod = static_cast<Module*>(CXMod);
6505 return Mod->IsSystem;
6506}
6507
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006508unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6509 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006510 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006511 LOG_BAD_TU(TU);
6512 return 0;
6513 }
6514 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 return 0;
6516 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006517 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6518 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6519 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006520}
6521
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006522CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6523 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006524 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006525 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006526 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006527 }
6528 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006529 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006531 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006532
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006533 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6534 if (Index < TopHeaders.size())
6535 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006536
Craig Topper69186e72014-06-08 08:38:04 +00006537 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006538}
6539
6540} // end: extern "C"
6541
6542//===----------------------------------------------------------------------===//
6543// C++ AST instrospection.
6544//===----------------------------------------------------------------------===//
6545
6546extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006547unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6548 if (!clang_isDeclaration(C.kind))
6549 return 0;
6550
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006551 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006552 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006553 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006554 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6555}
6556
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006557unsigned clang_CXXMethod_isConst(CXCursor C) {
6558 if (!clang_isDeclaration(C.kind))
6559 return 0;
6560
6561 const Decl *D = cxcursor::getCursorDecl(C);
6562 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006563 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006564 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6565}
6566
Guy Benyei11169dd2012-12-18 14:30:41 +00006567unsigned clang_CXXMethod_isStatic(CXCursor C) {
6568 if (!clang_isDeclaration(C.kind))
6569 return 0;
6570
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006571 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006572 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006573 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006574 return (Method && Method->isStatic()) ? 1 : 0;
6575}
6576
6577unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6578 if (!clang_isDeclaration(C.kind))
6579 return 0;
6580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006582 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006583 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 return (Method && Method->isVirtual()) ? 1 : 0;
6585}
6586} // end: extern "C"
6587
6588//===----------------------------------------------------------------------===//
6589// Attribute introspection.
6590//===----------------------------------------------------------------------===//
6591
6592extern "C" {
6593CXType clang_getIBOutletCollectionType(CXCursor C) {
6594 if (C.kind != CXCursor_IBOutletCollectionAttr)
6595 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6596
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006597 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6599
6600 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6601}
6602} // end: extern "C"
6603
6604//===----------------------------------------------------------------------===//
6605// Inspecting memory usage.
6606//===----------------------------------------------------------------------===//
6607
6608typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6609
6610static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6611 enum CXTUResourceUsageKind k,
6612 unsigned long amount) {
6613 CXTUResourceUsageEntry entry = { k, amount };
6614 entries.push_back(entry);
6615}
6616
6617extern "C" {
6618
6619const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6620 const char *str = "";
6621 switch (kind) {
6622 case CXTUResourceUsage_AST:
6623 str = "ASTContext: expressions, declarations, and types";
6624 break;
6625 case CXTUResourceUsage_Identifiers:
6626 str = "ASTContext: identifiers";
6627 break;
6628 case CXTUResourceUsage_Selectors:
6629 str = "ASTContext: selectors";
6630 break;
6631 case CXTUResourceUsage_GlobalCompletionResults:
6632 str = "Code completion: cached global results";
6633 break;
6634 case CXTUResourceUsage_SourceManagerContentCache:
6635 str = "SourceManager: content cache allocator";
6636 break;
6637 case CXTUResourceUsage_AST_SideTables:
6638 str = "ASTContext: side tables";
6639 break;
6640 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6641 str = "SourceManager: malloc'ed memory buffers";
6642 break;
6643 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6644 str = "SourceManager: mmap'ed memory buffers";
6645 break;
6646 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6647 str = "ExternalASTSource: malloc'ed memory buffers";
6648 break;
6649 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6650 str = "ExternalASTSource: mmap'ed memory buffers";
6651 break;
6652 case CXTUResourceUsage_Preprocessor:
6653 str = "Preprocessor: malloc'ed memory";
6654 break;
6655 case CXTUResourceUsage_PreprocessingRecord:
6656 str = "Preprocessor: PreprocessingRecord";
6657 break;
6658 case CXTUResourceUsage_SourceManager_DataStructures:
6659 str = "SourceManager: data structures and tables";
6660 break;
6661 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6662 str = "Preprocessor: header search tables";
6663 break;
6664 }
6665 return str;
6666}
6667
6668CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006669 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006670 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006671 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 return usage;
6673 }
6674
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006675 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006676 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 ASTContext &astContext = astUnit->getASTContext();
6678
6679 // How much memory is used by AST nodes and types?
6680 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6681 (unsigned long) astContext.getASTAllocatedMemory());
6682
6683 // How much memory is used by identifiers?
6684 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6685 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6686
6687 // How much memory is used for selectors?
6688 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6689 (unsigned long) astContext.Selectors.getTotalMemory());
6690
6691 // How much memory is used by ASTContext's side tables?
6692 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6693 (unsigned long) astContext.getSideTableAllocatedMemory());
6694
6695 // How much memory is used for caching global code completion results?
6696 unsigned long completionBytes = 0;
6697 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006698 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006699 completionBytes = completionAllocator->getTotalMemory();
6700 }
6701 createCXTUResourceUsageEntry(*entries,
6702 CXTUResourceUsage_GlobalCompletionResults,
6703 completionBytes);
6704
6705 // How much memory is being used by SourceManager's content cache?
6706 createCXTUResourceUsageEntry(*entries,
6707 CXTUResourceUsage_SourceManagerContentCache,
6708 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6709
6710 // How much memory is being used by the MemoryBuffer's in SourceManager?
6711 const SourceManager::MemoryBufferSizes &srcBufs =
6712 astUnit->getSourceManager().getMemoryBufferSizes();
6713
6714 createCXTUResourceUsageEntry(*entries,
6715 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6716 (unsigned long) srcBufs.malloc_bytes);
6717 createCXTUResourceUsageEntry(*entries,
6718 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6719 (unsigned long) srcBufs.mmap_bytes);
6720 createCXTUResourceUsageEntry(*entries,
6721 CXTUResourceUsage_SourceManager_DataStructures,
6722 (unsigned long) astContext.getSourceManager()
6723 .getDataStructureSizes());
6724
6725 // How much memory is being used by the ExternalASTSource?
6726 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6727 const ExternalASTSource::MemoryBufferSizes &sizes =
6728 esrc->getMemoryBufferSizes();
6729
6730 createCXTUResourceUsageEntry(*entries,
6731 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6732 (unsigned long) sizes.malloc_bytes);
6733 createCXTUResourceUsageEntry(*entries,
6734 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6735 (unsigned long) sizes.mmap_bytes);
6736 }
6737
6738 // How much memory is being used by the Preprocessor?
6739 Preprocessor &pp = astUnit->getPreprocessor();
6740 createCXTUResourceUsageEntry(*entries,
6741 CXTUResourceUsage_Preprocessor,
6742 pp.getTotalMemory());
6743
6744 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6745 createCXTUResourceUsageEntry(*entries,
6746 CXTUResourceUsage_PreprocessingRecord,
6747 pRec->getTotalMemory());
6748 }
6749
6750 createCXTUResourceUsageEntry(*entries,
6751 CXTUResourceUsage_Preprocessor_HeaderSearch,
6752 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006753
Guy Benyei11169dd2012-12-18 14:30:41 +00006754 CXTUResourceUsage usage = { (void*) entries.get(),
6755 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006756 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006757 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 return usage;
6759}
6760
6761void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6762 if (usage.data)
6763 delete (MemUsageEntries*) usage.data;
6764}
6765
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006766CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6767 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006768 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006769 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006770
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006771 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006772 LOG_BAD_TU(TU);
6773 return skipped;
6774 }
6775
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006776 if (!file)
6777 return skipped;
6778
6779 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6780 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6781 if (!ppRec)
6782 return skipped;
6783
6784 ASTContext &Ctx = astUnit->getASTContext();
6785 SourceManager &sm = Ctx.getSourceManager();
6786 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6787 FileID wantedFileID = sm.translateFile(fileEntry);
6788
6789 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6790 std::vector<SourceRange> wantedRanges;
6791 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6792 i != ei; ++i) {
6793 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6794 wantedRanges.push_back(*i);
6795 }
6796
6797 skipped->count = wantedRanges.size();
6798 skipped->ranges = new CXSourceRange[skipped->count];
6799 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6800 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6801
6802 return skipped;
6803}
6804
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006805void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6806 if (ranges) {
6807 delete[] ranges->ranges;
6808 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006809 }
6810}
6811
Guy Benyei11169dd2012-12-18 14:30:41 +00006812} // end extern "C"
6813
6814void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6815 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6816 for (unsigned I = 0; I != Usage.numEntries; ++I)
6817 fprintf(stderr, " %s: %lu\n",
6818 clang_getTUResourceUsageName(Usage.entries[I].kind),
6819 Usage.entries[I].amount);
6820
6821 clang_disposeCXTUResourceUsage(Usage);
6822}
6823
6824//===----------------------------------------------------------------------===//
6825// Misc. utility functions.
6826//===----------------------------------------------------------------------===//
6827
6828/// Default to using an 8 MB stack size on "safety" threads.
6829static unsigned SafetyStackThreadSize = 8 << 20;
6830
6831namespace clang {
6832
6833bool RunSafely(llvm::CrashRecoveryContext &CRC,
6834 void (*Fn)(void*), void *UserData,
6835 unsigned Size) {
6836 if (!Size)
6837 Size = GetSafetyThreadStackSize();
6838 if (Size)
6839 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6840 return CRC.RunSafely(Fn, UserData);
6841}
6842
6843unsigned GetSafetyThreadStackSize() {
6844 return SafetyStackThreadSize;
6845}
6846
6847void SetSafetyThreadStackSize(unsigned Value) {
6848 SafetyStackThreadSize = Value;
6849}
6850
6851}
6852
6853void clang::setThreadBackgroundPriority() {
6854 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6855 return;
6856
Alp Toker1a86ad22014-07-06 06:24:00 +00006857#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6859#endif
6860}
6861
6862void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6863 if (!Unit)
6864 return;
6865
6866 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6867 DEnd = Unit->stored_diag_end();
6868 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006869 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006870 CXString Msg = clang_formatDiagnostic(&Diag,
6871 clang_defaultDiagnosticDisplayOptions());
6872 fprintf(stderr, "%s\n", clang_getCString(Msg));
6873 clang_disposeString(Msg);
6874 }
6875#ifdef LLVM_ON_WIN32
6876 // On Windows, force a flush, since there may be multiple copies of
6877 // stderr and stdout in the file system, all with different buffers
6878 // but writing to the same device.
6879 fflush(stderr);
6880#endif
6881}
6882
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006883MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6884 SourceLocation MacroDefLoc,
6885 CXTranslationUnit TU){
6886 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006887 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006888 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006889 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006890
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006891 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006892 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006893 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006894 if (MD) {
6895 for (MacroDirective::DefInfo
6896 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6897 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6898 return Def.getMacroInfo();
6899 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006900 }
6901
Craig Topper69186e72014-06-08 08:38:04 +00006902 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006903}
6904
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006905const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6906 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006907 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006908 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006909 const IdentifierInfo *II = MacroDef->getName();
6910 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912
6913 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6914}
6915
6916MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6917 const Token &Tok,
6918 CXTranslationUnit TU) {
6919 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006920 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006921 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006922 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006923
6924 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006925 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006926 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6927 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006928 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006929
6930 // Check that the token is inside the definition and not its argument list.
6931 SourceManager &SM = Unit->getSourceManager();
6932 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006933 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006934 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936
6937 Preprocessor &PP = Unit->getPreprocessor();
6938 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6939 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006940 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006941
Alp Toker2d57cea2014-05-17 04:53:25 +00006942 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006943 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006944 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006945
6946 // Check that the identifier is not one of the macro arguments.
6947 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006948 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006949
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006950 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6951 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006953
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006954 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006955}
6956
6957MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6958 SourceLocation Loc,
6959 CXTranslationUnit TU) {
6960 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006961 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006962
6963 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006964 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006965 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006966 Preprocessor &PP = Unit->getPreprocessor();
6967 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006968 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006969 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6970 Token Tok;
6971 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006972 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006973
6974 return checkForMacroInMacroDefinition(MI, Tok, TU);
6975}
6976
Guy Benyei11169dd2012-12-18 14:30:41 +00006977extern "C" {
6978
6979CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006980 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006981}
6982
6983} // end: extern "C"
6984
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006985Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6986 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006987 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006988 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006989 if (Unit->isMainFileAST())
6990 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006991 return *this;
6992 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006993 } else {
6994 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006995 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006996 return *this;
6997}
6998
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006999Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7000 *this << FE->getName();
7001 return *this;
7002}
7003
7004Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7005 CXString cursorName = clang_getCursorDisplayName(cursor);
7006 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7007 clang_disposeString(cursorName);
7008 return *this;
7009}
7010
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007011Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7012 CXFile File;
7013 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007014 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007015 CXString FileName = clang_getFileName(File);
7016 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7017 clang_disposeString(FileName);
7018 return *this;
7019}
7020
7021Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7022 CXSourceLocation BLoc = clang_getRangeStart(range);
7023 CXSourceLocation ELoc = clang_getRangeEnd(range);
7024
7025 CXFile BFile;
7026 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007027 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007028
7029 CXFile EFile;
7030 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007031 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007032
7033 CXString BFileName = clang_getFileName(BFile);
7034 if (BFile == EFile) {
7035 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7036 BLine, BColumn, ELine, EColumn);
7037 } else {
7038 CXString EFileName = clang_getFileName(EFile);
7039 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7040 BLine, BColumn)
7041 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7042 ELine, EColumn);
7043 clang_disposeString(EFileName);
7044 }
7045 clang_disposeString(BFileName);
7046 return *this;
7047}
7048
7049Logger &cxindex::Logger::operator<<(CXString Str) {
7050 *this << clang_getCString(Str);
7051 return *this;
7052}
7053
7054Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7055 LogOS << Fmt;
7056 return *this;
7057}
7058
Chandler Carruth37ad2582014-06-27 15:14:39 +00007059static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7060
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007061cxindex::Logger::~Logger() {
7062 LogOS.flush();
7063
Chandler Carruth37ad2582014-06-27 15:14:39 +00007064 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007065
7066 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7067
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007068 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007069 OS << "[libclang:" << Name << ':';
7070
Alp Toker1a86ad22014-07-06 06:24:00 +00007071#ifdef USE_DARWIN_THREADS
7072 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007073 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7074 OS << tid << ':';
7075#endif
7076
7077 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7078 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7079 OS << Msg.str() << '\n';
7080
7081 if (Trace) {
7082 llvm::sys::PrintStackTrace(stderr);
7083 OS << "--------------------------------------------------\n";
7084 }
7085}