blob: 099302fe2c634e0b401534c5a43d2e6b18a08396 [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();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001787 case Stmt::OMPCriticalDirectiveClass:
1788 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001861 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001862 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001863 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001864 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001865 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001866 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001867 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001868 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001869 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001870 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001871 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001872 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001873 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001874 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001875 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876
Guy Benyei11169dd2012-12-18 14:30:41 +00001877private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1880 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1882 void AddStmt(const Stmt *S);
1883 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001886 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888} // end anonyous namespace
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 // 'S' should always be non-null, since it comes from the
1892 // statement we are visiting.
1893 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1894}
1895
1896void
1897EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1898 if (Qualifier)
1899 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1900}
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (S)
1904 WL.push_back(StmtVisit(S, Parent));
1905}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (D)
1908 WL.push_back(DeclVisit(D, Parent, isFirst));
1909}
1910void EnqueueVisitor::
1911 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1912 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001914}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001915void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 if (D)
1917 WL.push_back(MemberRefVisit(D, L, Parent));
1918}
1919void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1920 if (TI)
1921 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1922 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 AddStmt(*Child);
1927 }
1928 if (size == WL.size())
1929 return;
1930 // Now reverse the entries we just added. This will match the DFS
1931 // ordering performed by the worklist.
1932 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1933 std::reverse(I, E);
1934}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935namespace {
1936class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1937 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001938 /// \brief Process clauses with list of variables.
1939 template <typename T>
1940 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941public:
1942 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1943#define OPENMP_CLAUSE(Name, Class) \
1944 void Visit##Class(const Class *C);
1945#include "clang/Basic/OpenMPKinds.def"
1946};
1947
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001948void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1949 Visitor->AddStmt(C->getCondition());
1950}
1951
Alexey Bataev3778b602014-07-17 07:32:53 +00001952void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev568a8332014-03-06 06:15:19 +00001956void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1957 Visitor->AddStmt(C->getNumThreads());
1958}
1959
Alexey Bataev62c87d22014-03-21 04:51:18 +00001960void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1961 Visitor->AddStmt(C->getSafelen());
1962}
1963
Alexander Musman8bd31e62014-05-27 15:12:19 +00001964void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1965 Visitor->AddStmt(C->getNumForLoops());
1966}
1967
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001969
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001970void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1971
Alexey Bataev56dafe82014-06-20 07:16:17 +00001972void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1973 Visitor->AddStmt(C->getChunkSize());
1974}
1975
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001976void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1977
Alexey Bataev236070f2014-06-20 11:19:47 +00001978void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1979
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001980void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1981
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001982void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1983
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001984void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1985
Alexey Bataev756c1962013-09-24 03:17:45 +00001986template<typename T>
1987void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001988 for (const auto *I : Node->varlists())
1989 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001990}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001991
1992void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001993 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001994}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001995void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1996 const OMPFirstprivateClause *C) {
1997 VisitOMPClauseList(C);
1998}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001999void OMPClauseEnqueue::VisitOMPLastprivateClause(
2000 const OMPLastprivateClause *C) {
2001 VisitOMPClauseList(C);
2002}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002003void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002004 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002005}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002006void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2007 VisitOMPClauseList(C);
2008}
Alexander Musman8dba6642014-04-22 13:09:42 +00002009void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2010 VisitOMPClauseList(C);
2011 Visitor->AddStmt(C->getStep());
2012}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002013void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2014 VisitOMPClauseList(C);
2015 Visitor->AddStmt(C->getAlignment());
2016}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002017void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2018 VisitOMPClauseList(C);
2019}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002020void
2021OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2022 VisitOMPClauseList(C);
2023}
Alexey Bataev6125da92014-07-21 11:26:11 +00002024void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2025 VisitOMPClauseList(C);
2026}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002027}
Alexey Bataev756c1962013-09-24 03:17:45 +00002028
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002029void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2030 unsigned size = WL.size();
2031 OMPClauseEnqueue Visitor(this);
2032 Visitor.Visit(S);
2033 if (size == WL.size())
2034 return;
2035 // Now reverse the entries we just added. This will match the DFS
2036 // ordering performed by the worklist.
2037 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2038 std::reverse(I, E);
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 AddDecl(B->getBlockDecl());
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 EnqueueChildren(E);
2048 AddTypeLoc(E->getTypeSourceInfo());
2049}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2051 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 E = S->body_rend(); I != E; ++I) {
2053 AddStmt(*I);
2054 }
2055}
2056void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 AddStmt(S->getSubStmt());
2059 AddDeclarationNameInfo(S);
2060 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2061 AddNestedNameSpecifierLoc(QualifierLoc);
2062}
2063
2064void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2067 AddDeclarationNameInfo(E);
2068 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2069 AddNestedNameSpecifierLoc(QualifierLoc);
2070 if (!E->isImplicitAccess())
2071 AddStmt(E->getBase());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 // Enqueue the initializer , if any.
2075 AddStmt(E->getInitializer());
2076 // Enqueue the array size, if any.
2077 AddStmt(E->getArraySize());
2078 // Enqueue the allocated type.
2079 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2080 // Enqueue the placement arguments.
2081 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2082 AddStmt(E->getPlacementArg(I-1));
2083}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2086 AddStmt(CE->getArg(I-1));
2087 AddStmt(CE->getCallee());
2088 AddStmt(CE->getArg(0));
2089}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2091 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 // Visit the name of the type being destroyed.
2093 AddTypeLoc(E->getDestroyedTypeInfo());
2094 // Visit the scope type that looks disturbingly like the nested-name-specifier
2095 // but isn't.
2096 AddTypeLoc(E->getScopeTypeInfo());
2097 // Visit the nested-name-specifier.
2098 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2099 AddNestedNameSpecifierLoc(QualifierLoc);
2100 // Visit base expression.
2101 AddStmt(E->getBase());
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2104 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 AddTypeLoc(E->getTypeSourceInfo());
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2108 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 EnqueueChildren(E);
2110 AddTypeLoc(E->getTypeSourceInfo());
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 if (E->isTypeOperand())
2115 AddTypeLoc(E->getTypeOperandSourceInfo());
2116}
2117
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2119 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 AddTypeLoc(E->getTypeSourceInfo());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 EnqueueChildren(E);
2125 if (E->isTypeOperand())
2126 AddTypeLoc(E->getTypeOperandSourceInfo());
2127}
2128
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 EnqueueChildren(S);
2131 AddDecl(S->getExceptionDecl());
2132}
2133
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 if (DR->hasExplicitTemplateArgs()) {
2136 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2137 }
2138 WL.push_back(DeclRefExprParts(DR, Parent));
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2141 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2143 AddDeclarationNameInfo(E);
2144 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 unsigned size = WL.size();
2148 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002149 for (const auto *D : S->decls()) {
2150 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 isFirst = false;
2152 }
2153 if (size == WL.size())
2154 return;
2155 // Now reverse the entries we just added. This will match the DFS
2156 // ordering performed by the worklist.
2157 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2158 std::reverse(I, E);
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 D = E->designators_rbegin(), DEnd = E->designators_rend();
2164 D != DEnd; ++D) {
2165 if (D->isFieldDesignator()) {
2166 if (FieldDecl *Field = D->getField())
2167 AddMemberRef(Field, D->getFieldLoc());
2168 continue;
2169 }
2170 if (D->isArrayDesignator()) {
2171 AddStmt(E->getArrayIndex(*D));
2172 continue;
2173 }
2174 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2175 AddStmt(E->getArrayRangeEnd(*D));
2176 AddStmt(E->getArrayRangeStart(*D));
2177 }
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 EnqueueChildren(E);
2181 AddTypeLoc(E->getTypeInfoAsWritten());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 AddStmt(FS->getBody());
2185 AddStmt(FS->getInc());
2186 AddStmt(FS->getCond());
2187 AddDecl(FS->getConditionVariable());
2188 AddStmt(FS->getInit());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 AddStmt(If->getElse());
2195 AddStmt(If->getThen());
2196 AddStmt(If->getCond());
2197 AddDecl(If->getConditionVariable());
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 // We care about the syntactic form of the initializer list, only.
2201 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2202 IE = Syntactic;
2203 EnqueueChildren(IE);
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 WL.push_back(MemberExprParts(M, Parent));
2207
2208 // If the base of the member access expression is an implicit 'this', don't
2209 // visit it.
2210 // FIXME: If we ever want to show these implicit accesses, this will be
2211 // unfortunate. However, clang_getCursor() relies on this behavior.
2212 if (!M->isImplicitAccess())
2213 AddStmt(M->getBase());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 AddTypeLoc(E->getEncodedTypeSourceInfo());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 EnqueueChildren(M);
2220 AddTypeLoc(M->getClassReceiverTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 // Visit the components of the offsetof expression.
2224 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2225 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2226 const OffsetOfNode &Node = E->getComponent(I-1);
2227 switch (Node.getKind()) {
2228 case OffsetOfNode::Array:
2229 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2230 break;
2231 case OffsetOfNode::Field:
2232 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2233 break;
2234 case OffsetOfNode::Identifier:
2235 case OffsetOfNode::Base:
2236 continue;
2237 }
2238 }
2239 // Visit the type into which we're computing the offset.
2240 AddTypeLoc(E->getTypeSourceInfo());
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2244 WL.push_back(OverloadExprParts(E, Parent));
2245}
2246void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 EnqueueChildren(E);
2249 if (E->isArgumentType())
2250 AddTypeLoc(E->getArgumentTypeInfo());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 EnqueueChildren(S);
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 AddStmt(S->getBody());
2257 AddStmt(S->getCond());
2258 AddDecl(S->getConditionVariable());
2259}
2260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(W->getBody());
2263 AddStmt(W->getCond());
2264 AddDecl(W->getConditionVariable());
2265}
2266
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 for (unsigned I = E->getNumArgs(); I > 0; --I)
2269 AddTypeLoc(E->getArg(I-1));
2270}
2271
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddTypeLoc(E->getQueriedTypeSourceInfo());
2274}
2275
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278}
2279
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 VisitOverloadExpr(U);
2282 if (!U->isImplicitAccess())
2283 AddStmt(U->getBase());
2284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 AddStmt(E->getSubExpr());
2287 AddTypeLoc(E->getWrittenTypeInfo());
2288}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 WL.push_back(SizeOfPackExprParts(E, Parent));
2291}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 // If the opaque value has a source expression, just transparently
2294 // visit that. This is useful for (e.g.) pseudo-object expressions.
2295 if (Expr *SourceExpr = E->getSourceExpr())
2296 return Visit(SourceExpr);
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 AddStmt(E->getBody());
2300 WL.push_back(LambdaExprParts(E, Parent));
2301}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 // Treat the expression like its syntactic form.
2304 Visit(E->getSyntacticForm());
2305}
2306
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002307void EnqueueVisitor::VisitOMPExecutableDirective(
2308 const OMPExecutableDirective *D) {
2309 EnqueueChildren(D);
2310 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2311 E = D->clauses().end();
2312 I != E; ++I)
2313 EnqueueChildren(*I);
2314}
2315
2316void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002320void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2321 VisitOMPExecutableDirective(D);
2322}
2323
Alexey Bataevf29276e2014-06-18 04:14:57 +00002324void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002328void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002332void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002336void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexander Musman80c22892014-07-17 08:54:58 +00002340void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2341 VisitOMPExecutableDirective(D);
2342}
2343
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002344void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2345 VisitOMPExecutableDirective(D);
2346 AddDeclarationNameInfo(D);
2347}
2348
Alexey Bataev4acb8592014-07-07 13:01:15 +00002349void
2350EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2351 VisitOMPExecutableDirective(D);
2352}
2353
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002354void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2355 const OMPParallelSectionsDirective *D) {
2356 VisitOMPExecutableDirective(D);
2357}
2358
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002359void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2360 VisitOMPExecutableDirective(D);
2361}
2362
Alexey Bataev68446b72014-07-18 07:47:19 +00002363void
2364EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2365 VisitOMPExecutableDirective(D);
2366}
2367
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002368void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2369 VisitOMPExecutableDirective(D);
2370}
2371
Alexey Bataev2df347a2014-07-18 10:17:07 +00002372void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2373 VisitOMPExecutableDirective(D);
2374}
2375
Alexey Bataev6125da92014-07-21 11:26:11 +00002376void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2377 VisitOMPExecutableDirective(D);
2378}
2379
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002380void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2381 VisitOMPExecutableDirective(D);
2382}
2383
Alexey Bataev0162e452014-07-22 10:10:35 +00002384void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2385 VisitOMPExecutableDirective(D);
2386}
2387
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2390}
2391
2392bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2393 if (RegionOfInterest.isValid()) {
2394 SourceRange Range = getRawCursorExtent(C);
2395 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2396 return false;
2397 }
2398 return true;
2399}
2400
2401bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2402 while (!WL.empty()) {
2403 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002404 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002405
2406 // Set the Parent field, then back to its old value once we're done.
2407 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2408
2409 switch (LI.getKind()) {
2410 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 if (!D)
2413 continue;
2414
2415 // For now, perform default visitation for Decls.
2416 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2417 cast<DeclVisit>(&LI)->isFirst())))
2418 return true;
2419
2420 continue;
2421 }
2422 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2423 const ASTTemplateArgumentListInfo *ArgList =
2424 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2425 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2426 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2427 Arg != ArgEnd; ++Arg) {
2428 if (VisitTemplateArgumentLoc(*Arg))
2429 return true;
2430 }
2431 continue;
2432 }
2433 case VisitorJob::TypeLocVisitKind: {
2434 // Perform default visitation for TypeLocs.
2435 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2436 return true;
2437 continue;
2438 }
2439 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 if (LabelStmt *stmt = LS->getStmt()) {
2442 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2443 TU))) {
2444 return true;
2445 }
2446 }
2447 continue;
2448 }
2449
2450 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2451 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2452 if (VisitNestedNameSpecifierLoc(V->get()))
2453 return true;
2454 continue;
2455 }
2456
2457 case VisitorJob::DeclarationNameInfoVisitKind: {
2458 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2459 ->get()))
2460 return true;
2461 continue;
2462 }
2463 case VisitorJob::MemberRefVisitKind: {
2464 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2465 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2466 return true;
2467 continue;
2468 }
2469 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 if (!S)
2472 continue;
2473
2474 // Update the current cursor.
2475 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2476 if (!IsInRegionOfInterest(Cursor))
2477 continue;
2478 switch (Visitor(Cursor, Parent, ClientData)) {
2479 case CXChildVisit_Break: return true;
2480 case CXChildVisit_Continue: break;
2481 case CXChildVisit_Recurse:
2482 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002483 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 EnqueueWorkList(WL, S);
2485 break;
2486 }
2487 continue;
2488 }
2489 case VisitorJob::MemberExprPartsKind: {
2490 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002491 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002492
2493 // Visit the nested-name-specifier
2494 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2495 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2496 return true;
2497
2498 // Visit the declaration name.
2499 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2500 return true;
2501
2502 // Visit the explicitly-specified template arguments, if any.
2503 if (M->hasExplicitTemplateArgs()) {
2504 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2505 *ArgEnd = Arg + M->getNumTemplateArgs();
2506 Arg != ArgEnd; ++Arg) {
2507 if (VisitTemplateArgumentLoc(*Arg))
2508 return true;
2509 }
2510 }
2511 continue;
2512 }
2513 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 // Visit nested-name-specifier, if present.
2516 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2517 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2518 return true;
2519 // Visit declaration name.
2520 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2521 return true;
2522 continue;
2523 }
2524 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002525 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 // Visit the nested-name-specifier.
2527 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2528 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2529 return true;
2530 // Visit the declaration name.
2531 if (VisitDeclarationNameInfo(O->getNameInfo()))
2532 return true;
2533 // Visit the overloaded declaration reference.
2534 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2535 return true;
2536 continue;
2537 }
2538 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002539 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 NamedDecl *Pack = E->getPack();
2541 if (isa<TemplateTypeParmDecl>(Pack)) {
2542 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2543 E->getPackLoc(), TU)))
2544 return true;
2545
2546 continue;
2547 }
2548
2549 if (isa<TemplateTemplateParmDecl>(Pack)) {
2550 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2551 E->getPackLoc(), TU)))
2552 return true;
2553
2554 continue;
2555 }
2556
2557 // Non-type template parameter packs and function parameter packs are
2558 // treated like DeclRefExpr cursors.
2559 continue;
2560 }
2561
2562 case VisitorJob::LambdaExprPartsKind: {
2563 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002564 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2566 CEnd = E->explicit_capture_end();
2567 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002568 // FIXME: Lambda init-captures.
2569 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002570 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002571
Guy Benyei11169dd2012-12-18 14:30:41 +00002572 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2573 C->getLocation(),
2574 TU)))
2575 return true;
2576 }
2577
2578 // Visit parameters and return type, if present.
2579 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2580 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2581 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2582 // Visit the whole type.
2583 if (Visit(TL))
2584 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002585 } else if (FunctionProtoTypeLoc Proto =
2586 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 if (E->hasExplicitParameters()) {
2588 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002589 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2590 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002591 return true;
2592 } else {
2593 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002594 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 return true;
2596 }
2597 }
2598 }
2599 break;
2600 }
2601
2602 case VisitorJob::PostChildrenVisitKind:
2603 if (PostChildrenVisitor(Parent, ClientData))
2604 return true;
2605 break;
2606 }
2607 }
2608 return false;
2609}
2610
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002611bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002612 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 if (!WorkListFreeList.empty()) {
2614 WL = WorkListFreeList.back();
2615 WL->clear();
2616 WorkListFreeList.pop_back();
2617 }
2618 else {
2619 WL = new VisitorWorkList();
2620 WorkListCache.push_back(WL);
2621 }
2622 EnqueueWorkList(*WL, S);
2623 bool result = RunVisitorWorkList(*WL);
2624 WorkListFreeList.push_back(WL);
2625 return result;
2626}
2627
2628namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002629typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002630RefNamePieces
2631buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2632 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2633 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2635 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2636 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2637
2638 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2639
2640 RefNamePieces Pieces;
2641
2642 if (WantQualifier && QLoc.isValid())
2643 Pieces.push_back(QLoc);
2644
2645 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2646 Pieces.push_back(NI.getLoc());
2647
2648 if (WantTemplateArgs && TemplateArgs)
2649 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2650 TemplateArgs->RAngleLoc));
2651
2652 if (Kind == DeclarationName::CXXOperatorName) {
2653 Pieces.push_back(SourceLocation::getFromRawEncoding(
2654 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2655 Pieces.push_back(SourceLocation::getFromRawEncoding(
2656 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2657 }
2658
2659 if (WantSinglePiece) {
2660 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2661 Pieces.clear();
2662 Pieces.push_back(R);
2663 }
2664
2665 return Pieces;
2666}
2667}
2668
2669//===----------------------------------------------------------------------===//
2670// Misc. API hooks.
2671//===----------------------------------------------------------------------===//
2672
Chad Rosier05c71aa2013-03-27 18:28:23 +00002673static void fatal_error_handler(void *user_data, const std::string& reason,
2674 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 // Write the result out to stderr avoiding errs() because raw_ostreams can
2676 // call report_fatal_error.
2677 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2678 ::abort();
2679}
2680
Chandler Carruth66660742014-06-27 16:37:27 +00002681namespace {
2682struct RegisterFatalErrorHandler {
2683 RegisterFatalErrorHandler() {
2684 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2685 }
2686};
2687}
2688
2689static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2690
Guy Benyei11169dd2012-12-18 14:30:41 +00002691extern "C" {
2692CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2693 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 // We use crash recovery to make some of our APIs more reliable, implicitly
2695 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002696 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2697 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002698
Chandler Carruth66660742014-06-27 16:37:27 +00002699 // Look through the managed static to trigger construction of the managed
2700 // static which registers our fatal error handler. This ensures it is only
2701 // registered once.
2702 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002703
2704 CIndexer *CIdxr = new CIndexer();
2705 if (excludeDeclarationsFromPCH)
2706 CIdxr->setOnlyLocalDecls();
2707 if (displayDiagnostics)
2708 CIdxr->setDisplayDiagnostics();
2709
2710 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2711 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2712 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2713 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2714 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2715 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2716
2717 return CIdxr;
2718}
2719
2720void clang_disposeIndex(CXIndex CIdx) {
2721 if (CIdx)
2722 delete static_cast<CIndexer *>(CIdx);
2723}
2724
2725void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2726 if (CIdx)
2727 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2728}
2729
2730unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2731 if (CIdx)
2732 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2733 return 0;
2734}
2735
2736void clang_toggleCrashRecovery(unsigned isEnabled) {
2737 if (isEnabled)
2738 llvm::CrashRecoveryContext::Enable();
2739 else
2740 llvm::CrashRecoveryContext::Disable();
2741}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002742
Guy Benyei11169dd2012-12-18 14:30:41 +00002743CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2744 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002745 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002746 enum CXErrorCode Result =
2747 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002748 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 assert((TU && Result == CXError_Success) ||
2750 (!TU && Result != CXError_Success));
2751 return TU;
2752}
2753
2754enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2755 const char *ast_filename,
2756 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002757 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002758 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002759
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002760 if (!CIdx || !ast_filename || !out_TU)
2761 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002762
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002763 LOG_FUNC_SECTION {
2764 *Log << ast_filename;
2765 }
2766
Guy Benyei11169dd2012-12-18 14:30:41 +00002767 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2768 FileSystemOptions FileSystemOpts;
2769
2770 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002771 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002772 CXXIdx->getOnlyLocalDecls(), None,
2773 /*CaptureDiagnostics=*/true,
2774 /*AllowPCHWithCompilerErrors=*/true,
2775 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002776 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2777 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002778}
2779
2780unsigned clang_defaultEditingTranslationUnitOptions() {
2781 return CXTranslationUnit_PrecompiledPreamble |
2782 CXTranslationUnit_CacheCompletionResults;
2783}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002784
Guy Benyei11169dd2012-12-18 14:30:41 +00002785CXTranslationUnit
2786clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2787 const char *source_filename,
2788 int num_command_line_args,
2789 const char * const *command_line_args,
2790 unsigned num_unsaved_files,
2791 struct CXUnsavedFile *unsaved_files) {
2792 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2793 return clang_parseTranslationUnit(CIdx, source_filename,
2794 command_line_args, num_command_line_args,
2795 unsaved_files, num_unsaved_files,
2796 Options);
2797}
2798
2799struct ParseTranslationUnitInfo {
2800 CXIndex CIdx;
2801 const char *source_filename;
2802 const char *const *command_line_args;
2803 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002804 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002805 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002806 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002807 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002808};
2809static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002810 const ParseTranslationUnitInfo *PTUI =
2811 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002812 CXIndex CIdx = PTUI->CIdx;
2813 const char *source_filename = PTUI->source_filename;
2814 const char * const *command_line_args = PTUI->command_line_args;
2815 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002816 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002817 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002818
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002819 // Set up the initial return values.
2820 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002821 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002822
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002824 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002825 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002826 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002827 }
2828
Guy Benyei11169dd2012-12-18 14:30:41 +00002829 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2830
2831 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2832 setThreadBackgroundPriority();
2833
2834 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2835 // FIXME: Add a flag for modules.
2836 TranslationUnitKind TUKind
2837 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002838 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 = options & CXTranslationUnit_CacheCompletionResults;
2840 bool IncludeBriefCommentsInCodeCompletion
2841 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2842 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2843 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2844
2845 // Configure the diagnostics.
2846 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002847 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002848
2849 // Recover resources if we crash before exiting this function.
2850 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2851 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002852 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002853
Ahmed Charlesb8984322014-03-07 20:03:18 +00002854 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2855 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002856
2857 // Recover resources if we crash before exiting this function.
2858 llvm::CrashRecoveryContextCleanupRegistrar<
2859 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2860
Alp Toker9d85b182014-07-07 01:23:14 +00002861 for (auto &UF : PTUI->unsaved_files) {
2862 llvm::MemoryBuffer *MB =
2863 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2864 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 }
2866
Ahmed Charlesb8984322014-03-07 20:03:18 +00002867 std::unique_ptr<std::vector<const char *>> Args(
2868 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
2870 // Recover resources if we crash before exiting this method.
2871 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2872 ArgsCleanup(Args.get());
2873
2874 // Since the Clang C library is primarily used by batch tools dealing with
2875 // (often very broken) source code, where spell-checking can have a
2876 // significant negative impact on performance (particularly when
2877 // precompiled headers are involved), we disable it by default.
2878 // Only do this if we haven't found a spell-checking-related argument.
2879 bool FoundSpellCheckingArgument = false;
2880 for (int I = 0; I != num_command_line_args; ++I) {
2881 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2882 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2883 FoundSpellCheckingArgument = true;
2884 break;
2885 }
2886 }
2887 if (!FoundSpellCheckingArgument)
2888 Args->push_back("-fno-spell-checking");
2889
2890 Args->insert(Args->end(), command_line_args,
2891 command_line_args + num_command_line_args);
2892
2893 // The 'source_filename' argument is optional. If the caller does not
2894 // specify it then it is assumed that the source file is specified
2895 // in the actual argument list.
2896 // Put the source file after command_line_args otherwise if '-x' flag is
2897 // present it will be unused.
2898 if (source_filename)
2899 Args->push_back(source_filename);
2900
2901 // Do we need the detailed preprocessing record?
2902 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2903 Args->push_back("-Xclang");
2904 Args->push_back("-detailed-preprocessing-record");
2905 }
2906
2907 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002908 std::unique_ptr<ASTUnit> ErrUnit;
2909 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002910 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002911 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2912 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2913 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2914 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2915 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2916 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002917
2918 if (NumErrors != Diags->getClient()->getNumErrors()) {
2919 // Make sure to check that 'Unit' is non-NULL.
2920 if (CXXIdx->getDisplayDiagnostics())
2921 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2922 }
2923
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002924 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2925 PTUI->result = CXError_ASTReadError;
2926 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002927 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002928 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2929 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002930}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002931
2932CXTranslationUnit
2933clang_parseTranslationUnit(CXIndex CIdx,
2934 const char *source_filename,
2935 const char *const *command_line_args,
2936 int num_command_line_args,
2937 struct CXUnsavedFile *unsaved_files,
2938 unsigned num_unsaved_files,
2939 unsigned options) {
2940 CXTranslationUnit TU;
2941 enum CXErrorCode Result = clang_parseTranslationUnit2(
2942 CIdx, source_filename, command_line_args, num_command_line_args,
2943 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002944 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002945 assert((TU && Result == CXError_Success) ||
2946 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002947 return TU;
2948}
2949
2950enum CXErrorCode clang_parseTranslationUnit2(
2951 CXIndex CIdx,
2952 const char *source_filename,
2953 const char *const *command_line_args,
2954 int num_command_line_args,
2955 struct CXUnsavedFile *unsaved_files,
2956 unsigned num_unsaved_files,
2957 unsigned options,
2958 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002959 LOG_FUNC_SECTION {
2960 *Log << source_filename << ": ";
2961 for (int i = 0; i != num_command_line_args; ++i)
2962 *Log << command_line_args[i] << " ";
2963 }
2964
Alp Toker9d85b182014-07-07 01:23:14 +00002965 if (num_unsaved_files && !unsaved_files)
2966 return CXError_InvalidArguments;
2967
Alp Toker5c532982014-07-07 22:42:03 +00002968 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002969 ParseTranslationUnitInfo PTUI = {
2970 CIdx,
2971 source_filename,
2972 command_line_args,
2973 num_command_line_args,
2974 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2975 options,
2976 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002977 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 llvm::CrashRecoveryContext CRC;
2979
2980 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2981 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2982 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2983 fprintf(stderr, " 'command_line_args' : [");
2984 for (int i = 0; i != num_command_line_args; ++i) {
2985 if (i)
2986 fprintf(stderr, ", ");
2987 fprintf(stderr, "'%s'", command_line_args[i]);
2988 }
2989 fprintf(stderr, "],\n");
2990 fprintf(stderr, " 'unsaved_files' : [");
2991 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2992 if (i)
2993 fprintf(stderr, ", ");
2994 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2995 unsaved_files[i].Length);
2996 }
2997 fprintf(stderr, "],\n");
2998 fprintf(stderr, " 'options' : %d,\n", options);
2999 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000
3001 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003003 if (CXTranslationUnit *TU = PTUI.out_TU)
3004 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003005 }
Alp Toker5c532982014-07-07 22:42:03 +00003006
3007 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003008}
3009
3010unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3011 return CXSaveTranslationUnit_None;
3012}
3013
3014namespace {
3015
3016struct SaveTranslationUnitInfo {
3017 CXTranslationUnit TU;
3018 const char *FileName;
3019 unsigned options;
3020 CXSaveError result;
3021};
3022
3023}
3024
3025static void clang_saveTranslationUnit_Impl(void *UserData) {
3026 SaveTranslationUnitInfo *STUI =
3027 static_cast<SaveTranslationUnitInfo*>(UserData);
3028
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003029 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3031 setThreadBackgroundPriority();
3032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003033 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3035}
3036
3037int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3038 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003039 LOG_FUNC_SECTION {
3040 *Log << TU << ' ' << FileName;
3041 }
3042
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003043 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003044 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003046 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003047
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003048 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003049 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3050 if (!CXXUnit->hasSema())
3051 return CXSaveError_InvalidTU;
3052
3053 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3054
3055 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3056 getenv("LIBCLANG_NOTHREADS")) {
3057 clang_saveTranslationUnit_Impl(&STUI);
3058
3059 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3060 PrintLibclangResourceUsage(TU);
3061
3062 return STUI.result;
3063 }
3064
3065 // We have an AST that has invalid nodes due to compiler errors.
3066 // Use a crash recovery thread for protection.
3067
3068 llvm::CrashRecoveryContext CRC;
3069
3070 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3071 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3072 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3073 fprintf(stderr, " 'options' : %d,\n", options);
3074 fprintf(stderr, "}\n");
3075
3076 return CXSaveError_Unknown;
3077
3078 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3079 PrintLibclangResourceUsage(TU);
3080 }
3081
3082 return STUI.result;
3083}
3084
3085void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3086 if (CTUnit) {
3087 // If the translation unit has been marked as unsafe to free, just discard
3088 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003089 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3090 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003091 return;
3092
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003093 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003094 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3096 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003097 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 delete CTUnit;
3099 }
3100}
3101
3102unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3103 return CXReparse_None;
3104}
3105
3106struct ReparseTranslationUnitInfo {
3107 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003108 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003110 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003111};
3112
3113static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003114 const ReparseTranslationUnitInfo *RTUI =
3115 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117 unsigned options = RTUI->options;
3118 (void) options;
3119
3120 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003121 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003123 RTUI->result = CXError_InvalidArguments;
3124 return;
3125 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
3127 // Reset the associated diagnostics.
3128 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003129 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003131 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3133 setThreadBackgroundPriority();
3134
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003135 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003137
3138 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3139 new std::vector<ASTUnit::RemappedFile>());
3140
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 // Recover resources if we crash before exiting this function.
3142 llvm::CrashRecoveryContextCleanupRegistrar<
3143 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003144
3145 for (auto &UF : RTUI->unsaved_files) {
3146 llvm::MemoryBuffer *MB =
3147 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3148 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003151 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003152 RTUI->result = CXError_Success;
3153 else if (isASTReadError(CXXUnit))
3154 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003155}
3156
3157int clang_reparseTranslationUnit(CXTranslationUnit TU,
3158 unsigned num_unsaved_files,
3159 struct CXUnsavedFile *unsaved_files,
3160 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003161 LOG_FUNC_SECTION {
3162 *Log << TU;
3163 }
3164
Alp Toker9d85b182014-07-07 01:23:14 +00003165 if (num_unsaved_files && !unsaved_files)
3166 return CXError_InvalidArguments;
3167
Alp Toker5c532982014-07-07 22:42:03 +00003168 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003169 ReparseTranslationUnitInfo RTUI = {
3170 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003171 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003172
3173 if (getenv("LIBCLANG_NOTHREADS")) {
3174 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003175 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 }
3177
3178 llvm::CrashRecoveryContext CRC;
3179
3180 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3181 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003182 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003183 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3185 PrintLibclangResourceUsage(TU);
3186
Alp Toker5c532982014-07-07 22:42:03 +00003187 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003188}
3189
3190
3191CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003192 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003193 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003194 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003195 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003196
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003197 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003198 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003199}
3200
3201CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003202 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003203 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003204 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003205 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003206
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003207 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3209}
3210
3211} // end: extern "C"
3212
3213//===----------------------------------------------------------------------===//
3214// CXFile Operations.
3215//===----------------------------------------------------------------------===//
3216
3217extern "C" {
3218CXString clang_getFileName(CXFile SFile) {
3219 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003220 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003221
3222 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003223 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003224}
3225
3226time_t clang_getFileTime(CXFile SFile) {
3227 if (!SFile)
3228 return 0;
3229
3230 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3231 return FEnt->getModificationTime();
3232}
3233
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003234CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003235 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003236 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003237 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003238 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003239
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003240 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003241
3242 FileManager &FMgr = CXXUnit->getFileManager();
3243 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3244}
3245
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003246unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3247 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003248 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003249 LOG_BAD_TU(TU);
3250 return 0;
3251 }
3252
3253 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return 0;
3255
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003256 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 FileEntry *FEnt = static_cast<FileEntry *>(file);
3258 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3259 .isFileMultipleIncludeGuarded(FEnt);
3260}
3261
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003262int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3263 if (!file || !outID)
3264 return 1;
3265
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003266 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003267 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3268 outID->data[0] = ID.getDevice();
3269 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003270 outID->data[2] = FEnt->getModificationTime();
3271 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003272}
3273
Guy Benyei11169dd2012-12-18 14:30:41 +00003274} // end: extern "C"
3275
3276//===----------------------------------------------------------------------===//
3277// CXCursor Operations.
3278//===----------------------------------------------------------------------===//
3279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280static const Decl *getDeclFromExpr(const Stmt *E) {
3281 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 return getDeclFromExpr(CE->getSubExpr());
3283
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (PRE->isExplicitProperty())
3292 return PRE->getExplicitProperty();
3293 // It could be messaging both getter and setter as in:
3294 // ++myobj.myprop;
3295 // in which case prefer to associate the setter since it is less obvious
3296 // from inspecting the source that the setter is going to get called.
3297 if (PRE->isMessagingSetter())
3298 return PRE->getImplicitPropertySetter();
3299 return PRE->getImplicitPropertyGetter();
3300 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003301 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (Expr *Src = OVE->getSourceExpr())
3305 return getDeclFromExpr(Src);
3306
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003307 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003309 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 if (!CE->isElidable())
3311 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 return OME->getMethodDecl();
3314
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3319 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3322 isa<ParmVarDecl>(SizeOfPack->getPack()))
3323 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003324
3325 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326}
3327
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003328static SourceLocation getLocationFromExpr(const Expr *E) {
3329 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 return getLocationFromExpr(CE->getSubExpr());
3331
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003332 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003334 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003336 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003338 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003340 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003342 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 return PropRef->getLocation();
3344
3345 return E->getLocStart();
3346}
3347
3348extern "C" {
3349
3350unsigned clang_visitChildren(CXCursor parent,
3351 CXCursorVisitor visitor,
3352 CXClientData client_data) {
3353 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3354 /*VisitPreprocessorLast=*/false);
3355 return CursorVis.VisitChildren(parent);
3356}
3357
3358#ifndef __has_feature
3359#define __has_feature(x) 0
3360#endif
3361#if __has_feature(blocks)
3362typedef enum CXChildVisitResult
3363 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3364
3365static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3366 CXClientData client_data) {
3367 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3368 return block(cursor, parent);
3369}
3370#else
3371// If we are compiled with a compiler that doesn't have native blocks support,
3372// define and call the block manually, so the
3373typedef struct _CXChildVisitResult
3374{
3375 void *isa;
3376 int flags;
3377 int reserved;
3378 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3379 CXCursor);
3380} *CXCursorVisitorBlock;
3381
3382static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3383 CXClientData client_data) {
3384 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3385 return block->invoke(block, cursor, parent);
3386}
3387#endif
3388
3389
3390unsigned clang_visitChildrenWithBlock(CXCursor parent,
3391 CXCursorVisitorBlock block) {
3392 return clang_visitChildren(parent, visitWithBlock, block);
3393}
3394
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003395static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003397 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003398
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003399 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const ObjCPropertyImplDecl *PropImpl =
3402 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003404 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003408 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003409
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003410 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003413 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003414 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3418 // and returns different names. NamedDecl returns the class name and
3419 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
3422 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003423 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003424
3425 SmallString<1024> S;
3426 llvm::raw_svector_ostream os(S);
3427 ND->printName(os);
3428
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430}
3431
3432CXString clang_getCursorSpelling(CXCursor C) {
3433 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003434 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003435
3436 if (clang_isReference(C.kind)) {
3437 switch (C.kind) {
3438 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003439 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003440 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003443 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003444 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003447 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003449 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
3451 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003452 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003456 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 assert(Type && "Missing type decl");
3458
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003459 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 getAsString());
3461 }
3462 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003463 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 assert(Template && "Missing template decl");
3465
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003466 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 }
3468
3469 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003470 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 assert(NS && "Missing namespace decl");
3472
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003473 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475
3476 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003477 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 assert(Field && "Missing member decl");
3479
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003480 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 }
3482
3483 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003484 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 assert(Label && "Missing label");
3486
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003487 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 }
3489
3490 case CXCursor_OverloadedDeclRef: {
3491 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3493 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003494 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003495 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003498 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 OverloadedTemplateStorage *Ovl
3500 = Storage.get<OverloadedTemplateStorage*>();
3501 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003502 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003503 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505
3506 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003507 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 assert(Var && "Missing variable decl");
3509
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003510 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 }
3512
3513 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003514 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 }
3516 }
3517
3518 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003519 const Expr *E = getCursorExpr(C);
3520
3521 if (C.kind == CXCursor_ObjCStringLiteral ||
3522 C.kind == CXCursor_StringLiteral) {
3523 const StringLiteral *SLit;
3524 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3525 SLit = OSL->getString();
3526 } else {
3527 SLit = cast<StringLiteral>(E);
3528 }
3529 SmallString<256> Buf;
3530 llvm::raw_svector_ostream OS(Buf);
3531 SLit->outputString(OS);
3532 return cxstring::createDup(OS.str());
3533 }
3534
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 if (D)
3537 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003538 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 }
3540
3541 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003542 const Stmt *S = getCursorStmt(C);
3543 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003546 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 }
3548
3549 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 ->getNameStart());
3552
3553 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003554 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 ->getNameStart());
3556
3557 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559
3560 if (clang_isDeclaration(C.kind))
3561 return getDeclSpelling(getCursorDecl(C));
3562
3563 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003564 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003565 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 }
3567
3568 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003569 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003570 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 }
3572
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003573 if (C.kind == CXCursor_PackedAttr) {
3574 return cxstring::createRef("packed");
3575 }
3576
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003577 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003578}
3579
3580CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3581 unsigned pieceIndex,
3582 unsigned options) {
3583 if (clang_Cursor_isNull(C))
3584 return clang_getNullRange();
3585
3586 ASTContext &Ctx = getCursorContext(C);
3587
3588 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003589 const Stmt *S = getCursorStmt(C);
3590 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 if (pieceIndex > 0)
3592 return clang_getNullRange();
3593 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3594 }
3595
3596 return clang_getNullRange();
3597 }
3598
3599 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003600 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3602 if (pieceIndex >= ME->getNumSelectorLocs())
3603 return clang_getNullRange();
3604 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3605 }
3606 }
3607
3608 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3609 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003610 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3612 if (pieceIndex >= MD->getNumSelectorLocs())
3613 return clang_getNullRange();
3614 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3615 }
3616 }
3617
3618 if (C.kind == CXCursor_ObjCCategoryDecl ||
3619 C.kind == CXCursor_ObjCCategoryImplDecl) {
3620 if (pieceIndex > 0)
3621 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003622 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3624 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003625 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3627 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3628 }
3629
3630 if (C.kind == CXCursor_ModuleImportDecl) {
3631 if (pieceIndex > 0)
3632 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003633 if (const ImportDecl *ImportD =
3634 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3636 if (!Locs.empty())
3637 return cxloc::translateSourceRange(Ctx,
3638 SourceRange(Locs.front(), Locs.back()));
3639 }
3640 return clang_getNullRange();
3641 }
3642
3643 // FIXME: A CXCursor_InclusionDirective should give the location of the
3644 // filename, but we don't keep track of this.
3645
3646 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3647 // but we don't keep track of this.
3648
3649 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3650 // but we don't keep track of this.
3651
3652 // Default handling, give the location of the cursor.
3653
3654 if (pieceIndex > 0)
3655 return clang_getNullRange();
3656
3657 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3658 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3659 return cxloc::translateSourceRange(Ctx, Loc);
3660}
3661
3662CXString clang_getCursorDisplayName(CXCursor C) {
3663 if (!clang_isDeclaration(C.kind))
3664 return clang_getCursorSpelling(C);
3665
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003666 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003668 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003669
3670 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003671 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 D = FunTmpl->getTemplatedDecl();
3673
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 SmallString<64> Str;
3676 llvm::raw_svector_ostream OS(Str);
3677 OS << *Function;
3678 if (Function->getPrimaryTemplate())
3679 OS << "<>";
3680 OS << "(";
3681 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3682 if (I)
3683 OS << ", ";
3684 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3685 }
3686
3687 if (Function->isVariadic()) {
3688 if (Function->getNumParams())
3689 OS << ", ";
3690 OS << "...";
3691 }
3692 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003693 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 }
3695
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003696 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 SmallString<64> Str;
3698 llvm::raw_svector_ostream OS(Str);
3699 OS << *ClassTemplate;
3700 OS << "<";
3701 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3702 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3703 if (I)
3704 OS << ", ";
3705
3706 NamedDecl *Param = Params->getParam(I);
3707 if (Param->getIdentifier()) {
3708 OS << Param->getIdentifier()->getName();
3709 continue;
3710 }
3711
3712 // There is no parameter name, which makes this tricky. Try to come up
3713 // with something useful that isn't too long.
3714 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3715 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3716 else if (NonTypeTemplateParmDecl *NTTP
3717 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3718 OS << NTTP->getType().getAsString(Policy);
3719 else
3720 OS << "template<...> class";
3721 }
3722
3723 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003724 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 }
3726
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003727 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3729 // If the type was explicitly written, use that.
3730 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003731 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003732
Benjamin Kramer9170e912013-02-22 15:46:01 +00003733 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 llvm::raw_svector_ostream OS(Str);
3735 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003736 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 ClassSpec->getTemplateArgs().data(),
3738 ClassSpec->getTemplateArgs().size(),
3739 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003740 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 }
3742
3743 return clang_getCursorSpelling(C);
3744}
3745
3746CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3747 switch (Kind) {
3748 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003876 case CXCursor_ObjCSelfExpr:
3877 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003966 case CXCursor_SEHLeaveStmt:
3967 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003996 case CXCursor_PackedAttr:
3997 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003998 case CXCursor_PureAttr:
3999 return cxstring::createRef("attribute(pure)");
4000 case CXCursor_ConstAttr:
4001 return cxstring::createRef("attribute(const)");
4002 case CXCursor_NoDuplicateAttr:
4003 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004004 case CXCursor_CUDAConstantAttr:
4005 return cxstring::createRef("attribute(constant)");
4006 case CXCursor_CUDADeviceAttr:
4007 return cxstring::createRef("attribute(device)");
4008 case CXCursor_CUDAGlobalAttr:
4009 return cxstring::createRef("attribute(global)");
4010 case CXCursor_CUDAHostAttr:
4011 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004060 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004061 return cxstring::createRef("OMPParallelDirective");
4062 case CXCursor_OMPSimdDirective:
4063 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004064 case CXCursor_OMPForDirective:
4065 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004066 case CXCursor_OMPSectionsDirective:
4067 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004068 case CXCursor_OMPSectionDirective:
4069 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004070 case CXCursor_OMPSingleDirective:
4071 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004072 case CXCursor_OMPMasterDirective:
4073 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004074 case CXCursor_OMPCriticalDirective:
4075 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004076 case CXCursor_OMPParallelForDirective:
4077 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004078 case CXCursor_OMPParallelSectionsDirective:
4079 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004080 case CXCursor_OMPTaskDirective:
4081 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004082 case CXCursor_OMPTaskyieldDirective:
4083 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004084 case CXCursor_OMPBarrierDirective:
4085 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004086 case CXCursor_OMPTaskwaitDirective:
4087 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004088 case CXCursor_OMPFlushDirective:
4089 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004090 case CXCursor_OMPOrderedDirective:
4091 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004092 case CXCursor_OMPAtomicDirective:
4093 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 }
4095
4096 llvm_unreachable("Unhandled CXCursorKind");
4097}
4098
4099struct GetCursorData {
4100 SourceLocation TokenBeginLoc;
4101 bool PointsAtMacroArgExpansion;
4102 bool VisitedObjCPropertyImplDecl;
4103 SourceLocation VisitedDeclaratorDeclStartLoc;
4104 CXCursor &BestCursor;
4105
4106 GetCursorData(SourceManager &SM,
4107 SourceLocation tokenBegin, CXCursor &outputCursor)
4108 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4109 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4110 VisitedObjCPropertyImplDecl = false;
4111 }
4112};
4113
4114static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4115 CXCursor parent,
4116 CXClientData client_data) {
4117 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4118 CXCursor *BestCursor = &Data->BestCursor;
4119
4120 // If we point inside a macro argument we should provide info of what the
4121 // token is so use the actual cursor, don't replace it with a macro expansion
4122 // cursor.
4123 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4124 return CXChildVisit_Recurse;
4125
4126 if (clang_isDeclaration(cursor.kind)) {
4127 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004128 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4130 if (MD->isImplicit())
4131 return CXChildVisit_Break;
4132
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004133 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4135 // Check that when we have multiple @class references in the same line,
4136 // that later ones do not override the previous ones.
4137 // If we have:
4138 // @class Foo, Bar;
4139 // source ranges for both start at '@', so 'Bar' will end up overriding
4140 // 'Foo' even though the cursor location was at 'Foo'.
4141 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4142 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004143 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4145 if (PrevID != ID &&
4146 !PrevID->isThisDeclarationADefinition() &&
4147 !ID->isThisDeclarationADefinition())
4148 return CXChildVisit_Break;
4149 }
4150
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004151 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4153 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4154 // Check that when we have multiple declarators in the same line,
4155 // that later ones do not override the previous ones.
4156 // If we have:
4157 // int Foo, Bar;
4158 // source ranges for both start at 'int', so 'Bar' will end up overriding
4159 // 'Foo' even though the cursor location was at 'Foo'.
4160 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4161 return CXChildVisit_Break;
4162 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004164 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4166 (void)PropImp;
4167 // Check that when we have multiple @synthesize in the same line,
4168 // that later ones do not override the previous ones.
4169 // If we have:
4170 // @synthesize Foo, Bar;
4171 // source ranges for both start at '@', so 'Bar' will end up overriding
4172 // 'Foo' even though the cursor location was at 'Foo'.
4173 if (Data->VisitedObjCPropertyImplDecl)
4174 return CXChildVisit_Break;
4175 Data->VisitedObjCPropertyImplDecl = true;
4176 }
4177 }
4178
4179 if (clang_isExpression(cursor.kind) &&
4180 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004181 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 // Avoid having the cursor of an expression replace the declaration cursor
4183 // when the expression source range overlaps the declaration range.
4184 // This can happen for C++ constructor expressions whose range generally
4185 // include the variable declaration, e.g.:
4186 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4187 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4188 D->getLocation() == Data->TokenBeginLoc)
4189 return CXChildVisit_Break;
4190 }
4191 }
4192
4193 // If our current best cursor is the construction of a temporary object,
4194 // don't replace that cursor with a type reference, because we want
4195 // clang_getCursor() to point at the constructor.
4196 if (clang_isExpression(BestCursor->kind) &&
4197 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4198 cursor.kind == CXCursor_TypeRef) {
4199 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4200 // as having the actual point on the type reference.
4201 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4202 return CXChildVisit_Recurse;
4203 }
4204
4205 *BestCursor = cursor;
4206 return CXChildVisit_Recurse;
4207}
4208
4209CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004210 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004211 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004213 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4217
4218 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4219 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4220
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004221 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 CXFile SearchFile;
4223 unsigned SearchLine, SearchColumn;
4224 CXFile ResultFile;
4225 unsigned ResultLine, ResultColumn;
4226 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4227 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4228 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004229
4230 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4231 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004232 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004233 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 SearchFileName = clang_getFileName(SearchFile);
4235 ResultFileName = clang_getFileName(ResultFile);
4236 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4237 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004238 *Log << llvm::format("(%s:%d:%d) = %s",
4239 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4240 clang_getCString(KindSpelling))
4241 << llvm::format("(%s:%d:%d):%s%s",
4242 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4243 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 clang_disposeString(SearchFileName);
4245 clang_disposeString(ResultFileName);
4246 clang_disposeString(KindSpelling);
4247 clang_disposeString(USR);
4248
4249 CXCursor Definition = clang_getCursorDefinition(Result);
4250 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4251 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4252 CXString DefinitionKindSpelling
4253 = clang_getCursorKindSpelling(Definition.kind);
4254 CXFile DefinitionFile;
4255 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004256 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004257 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004259 *Log << llvm::format(" -> %s(%s:%d:%d)",
4260 clang_getCString(DefinitionKindSpelling),
4261 clang_getCString(DefinitionFileName),
4262 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 clang_disposeString(DefinitionFileName);
4264 clang_disposeString(DefinitionKindSpelling);
4265 }
4266 }
4267
4268 return Result;
4269}
4270
4271CXCursor clang_getNullCursor(void) {
4272 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4273}
4274
4275unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004276 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4277 // can't set consistently. For example, when visiting a DeclStmt we will set
4278 // it but we don't set it on the result of clang_getCursorDefinition for
4279 // a reference of the same declaration.
4280 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4281 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4282 // to provide that kind of info.
4283 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004284 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004285 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004286 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004287
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 return X == Y;
4289}
4290
4291unsigned clang_hashCursor(CXCursor C) {
4292 unsigned Index = 0;
4293 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4294 Index = 1;
4295
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004296 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 std::make_pair(C.kind, C.data[Index]));
4298}
4299
4300unsigned clang_isInvalid(enum CXCursorKind K) {
4301 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4302}
4303
4304unsigned clang_isDeclaration(enum CXCursorKind K) {
4305 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4306 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4307}
4308
4309unsigned clang_isReference(enum CXCursorKind K) {
4310 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4311}
4312
4313unsigned clang_isExpression(enum CXCursorKind K) {
4314 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4315}
4316
4317unsigned clang_isStatement(enum CXCursorKind K) {
4318 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4319}
4320
4321unsigned clang_isAttribute(enum CXCursorKind K) {
4322 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4323}
4324
4325unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4326 return K == CXCursor_TranslationUnit;
4327}
4328
4329unsigned clang_isPreprocessing(enum CXCursorKind K) {
4330 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4331}
4332
4333unsigned clang_isUnexposed(enum CXCursorKind K) {
4334 switch (K) {
4335 case CXCursor_UnexposedDecl:
4336 case CXCursor_UnexposedExpr:
4337 case CXCursor_UnexposedStmt:
4338 case CXCursor_UnexposedAttr:
4339 return true;
4340 default:
4341 return false;
4342 }
4343}
4344
4345CXCursorKind clang_getCursorKind(CXCursor C) {
4346 return C.kind;
4347}
4348
4349CXSourceLocation clang_getCursorLocation(CXCursor C) {
4350 if (clang_isReference(C.kind)) {
4351 switch (C.kind) {
4352 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004353 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 = getCursorObjCSuperClassRef(C);
4355 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4356 }
4357
4358 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004359 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 = getCursorObjCProtocolRef(C);
4361 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4362 }
4363
4364 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004365 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 = getCursorObjCClassRef(C);
4367 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4368 }
4369
4370 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004371 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4373 }
4374
4375 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004376 std::pair<const TemplateDecl *, SourceLocation> P =
4377 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4379 }
4380
4381 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004382 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4384 }
4385
4386 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004387 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4389 }
4390
4391 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004392 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4394 }
4395
4396 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004397 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 if (!BaseSpec)
4399 return clang_getNullLocation();
4400
4401 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4402 return cxloc::translateSourceLocation(getCursorContext(C),
4403 TSInfo->getTypeLoc().getBeginLoc());
4404
4405 return cxloc::translateSourceLocation(getCursorContext(C),
4406 BaseSpec->getLocStart());
4407 }
4408
4409 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004410 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4412 }
4413
4414 case CXCursor_OverloadedDeclRef:
4415 return cxloc::translateSourceLocation(getCursorContext(C),
4416 getCursorOverloadedDeclRef(C).second);
4417
4418 default:
4419 // FIXME: Need a way to enumerate all non-reference cases.
4420 llvm_unreachable("Missed a reference kind");
4421 }
4422 }
4423
4424 if (clang_isExpression(C.kind))
4425 return cxloc::translateSourceLocation(getCursorContext(C),
4426 getLocationFromExpr(getCursorExpr(C)));
4427
4428 if (clang_isStatement(C.kind))
4429 return cxloc::translateSourceLocation(getCursorContext(C),
4430 getCursorStmt(C)->getLocStart());
4431
4432 if (C.kind == CXCursor_PreprocessingDirective) {
4433 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4434 return cxloc::translateSourceLocation(getCursorContext(C), L);
4435 }
4436
4437 if (C.kind == CXCursor_MacroExpansion) {
4438 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004439 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 return cxloc::translateSourceLocation(getCursorContext(C), L);
4441 }
4442
4443 if (C.kind == CXCursor_MacroDefinition) {
4444 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4445 return cxloc::translateSourceLocation(getCursorContext(C), L);
4446 }
4447
4448 if (C.kind == CXCursor_InclusionDirective) {
4449 SourceLocation L
4450 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4451 return cxloc::translateSourceLocation(getCursorContext(C), L);
4452 }
4453
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004454 if (clang_isAttribute(C.kind)) {
4455 SourceLocation L
4456 = cxcursor::getCursorAttr(C)->getLocation();
4457 return cxloc::translateSourceLocation(getCursorContext(C), L);
4458 }
4459
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 if (!clang_isDeclaration(C.kind))
4461 return clang_getNullLocation();
4462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004463 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 if (!D)
4465 return clang_getNullLocation();
4466
4467 SourceLocation Loc = D->getLocation();
4468 // FIXME: Multiple variables declared in a single declaration
4469 // currently lack the information needed to correctly determine their
4470 // ranges when accounting for the type-specifier. We use context
4471 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4472 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004473 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 if (!cxcursor::isFirstInDeclGroup(C))
4475 Loc = VD->getLocation();
4476 }
4477
4478 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004479 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 Loc = MD->getSelectorStartLoc();
4481
4482 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4483}
4484
4485} // end extern "C"
4486
4487CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4488 assert(TU);
4489
4490 // Guard against an invalid SourceLocation, or we may assert in one
4491 // of the following calls.
4492 if (SLoc.isInvalid())
4493 return clang_getNullCursor();
4494
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004495 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496
4497 // Translate the given source location to make it point at the beginning of
4498 // the token under the cursor.
4499 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4500 CXXUnit->getASTContext().getLangOpts());
4501
4502 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4503 if (SLoc.isValid()) {
4504 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4505 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4506 /*VisitPreprocessorLast=*/true,
4507 /*VisitIncludedEntities=*/false,
4508 SourceLocation(SLoc));
4509 CursorVis.visitFileRegion();
4510 }
4511
4512 return Result;
4513}
4514
4515static SourceRange getRawCursorExtent(CXCursor C) {
4516 if (clang_isReference(C.kind)) {
4517 switch (C.kind) {
4518 case CXCursor_ObjCSuperClassRef:
4519 return getCursorObjCSuperClassRef(C).second;
4520
4521 case CXCursor_ObjCProtocolRef:
4522 return getCursorObjCProtocolRef(C).second;
4523
4524 case CXCursor_ObjCClassRef:
4525 return getCursorObjCClassRef(C).second;
4526
4527 case CXCursor_TypeRef:
4528 return getCursorTypeRef(C).second;
4529
4530 case CXCursor_TemplateRef:
4531 return getCursorTemplateRef(C).second;
4532
4533 case CXCursor_NamespaceRef:
4534 return getCursorNamespaceRef(C).second;
4535
4536 case CXCursor_MemberRef:
4537 return getCursorMemberRef(C).second;
4538
4539 case CXCursor_CXXBaseSpecifier:
4540 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4541
4542 case CXCursor_LabelRef:
4543 return getCursorLabelRef(C).second;
4544
4545 case CXCursor_OverloadedDeclRef:
4546 return getCursorOverloadedDeclRef(C).second;
4547
4548 case CXCursor_VariableRef:
4549 return getCursorVariableRef(C).second;
4550
4551 default:
4552 // FIXME: Need a way to enumerate all non-reference cases.
4553 llvm_unreachable("Missed a reference kind");
4554 }
4555 }
4556
4557 if (clang_isExpression(C.kind))
4558 return getCursorExpr(C)->getSourceRange();
4559
4560 if (clang_isStatement(C.kind))
4561 return getCursorStmt(C)->getSourceRange();
4562
4563 if (clang_isAttribute(C.kind))
4564 return getCursorAttr(C)->getRange();
4565
4566 if (C.kind == CXCursor_PreprocessingDirective)
4567 return cxcursor::getCursorPreprocessingDirective(C);
4568
4569 if (C.kind == CXCursor_MacroExpansion) {
4570 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004571 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 return TU->mapRangeFromPreamble(Range);
4573 }
4574
4575 if (C.kind == CXCursor_MacroDefinition) {
4576 ASTUnit *TU = getCursorASTUnit(C);
4577 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4578 return TU->mapRangeFromPreamble(Range);
4579 }
4580
4581 if (C.kind == CXCursor_InclusionDirective) {
4582 ASTUnit *TU = getCursorASTUnit(C);
4583 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4584 return TU->mapRangeFromPreamble(Range);
4585 }
4586
4587 if (C.kind == CXCursor_TranslationUnit) {
4588 ASTUnit *TU = getCursorASTUnit(C);
4589 FileID MainID = TU->getSourceManager().getMainFileID();
4590 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4591 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4592 return SourceRange(Start, End);
4593 }
4594
4595 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004596 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 if (!D)
4598 return SourceRange();
4599
4600 SourceRange R = D->getSourceRange();
4601 // FIXME: Multiple variables declared in a single declaration
4602 // currently lack the information needed to correctly determine their
4603 // ranges when accounting for the type-specifier. We use context
4604 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4605 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004606 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 if (!cxcursor::isFirstInDeclGroup(C))
4608 R.setBegin(VD->getLocation());
4609 }
4610 return R;
4611 }
4612 return SourceRange();
4613}
4614
4615/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4616/// the decl-specifier-seq for declarations.
4617static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4618 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004619 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 if (!D)
4621 return SourceRange();
4622
4623 SourceRange R = D->getSourceRange();
4624
4625 // Adjust the start of the location for declarations preceded by
4626 // declaration specifiers.
4627 SourceLocation StartLoc;
4628 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4629 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4630 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004631 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4633 StartLoc = TI->getTypeLoc().getLocStart();
4634 }
4635
4636 if (StartLoc.isValid() && R.getBegin().isValid() &&
4637 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4638 R.setBegin(StartLoc);
4639
4640 // FIXME: Multiple variables declared in a single declaration
4641 // currently lack the information needed to correctly determine their
4642 // ranges when accounting for the type-specifier. We use context
4643 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4644 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004645 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 if (!cxcursor::isFirstInDeclGroup(C))
4647 R.setBegin(VD->getLocation());
4648 }
4649
4650 return R;
4651 }
4652
4653 return getRawCursorExtent(C);
4654}
4655
4656extern "C" {
4657
4658CXSourceRange clang_getCursorExtent(CXCursor C) {
4659 SourceRange R = getRawCursorExtent(C);
4660 if (R.isInvalid())
4661 return clang_getNullRange();
4662
4663 return cxloc::translateSourceRange(getCursorContext(C), R);
4664}
4665
4666CXCursor clang_getCursorReferenced(CXCursor C) {
4667 if (clang_isInvalid(C.kind))
4668 return clang_getNullCursor();
4669
4670 CXTranslationUnit tu = getCursorTU(C);
4671 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004672 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 if (!D)
4674 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004675 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004677 if (const ObjCPropertyImplDecl *PropImpl =
4678 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4680 return MakeCXCursor(Property, tu);
4681
4682 return C;
4683 }
4684
4685 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004686 const Expr *E = getCursorExpr(C);
4687 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 if (D) {
4689 CXCursor declCursor = MakeCXCursor(D, tu);
4690 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4691 declCursor);
4692 return declCursor;
4693 }
4694
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004695 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 return MakeCursorOverloadedDeclRef(Ovl, tu);
4697
4698 return clang_getNullCursor();
4699 }
4700
4701 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004702 const Stmt *S = getCursorStmt(C);
4703 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 if (LabelDecl *label = Goto->getLabel())
4705 if (LabelStmt *labelS = label->getStmt())
4706 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4707
4708 return clang_getNullCursor();
4709 }
4710
4711 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004712 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 return MakeMacroDefinitionCursor(Def, tu);
4714 }
4715
4716 if (!clang_isReference(C.kind))
4717 return clang_getNullCursor();
4718
4719 switch (C.kind) {
4720 case CXCursor_ObjCSuperClassRef:
4721 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4722
4723 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004724 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4725 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 return MakeCXCursor(Def, tu);
4727
4728 return MakeCXCursor(Prot, tu);
4729 }
4730
4731 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004732 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4733 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 return MakeCXCursor(Def, tu);
4735
4736 return MakeCXCursor(Class, tu);
4737 }
4738
4739 case CXCursor_TypeRef:
4740 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4741
4742 case CXCursor_TemplateRef:
4743 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4744
4745 case CXCursor_NamespaceRef:
4746 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4747
4748 case CXCursor_MemberRef:
4749 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4750
4751 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004752 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4754 tu ));
4755 }
4756
4757 case CXCursor_LabelRef:
4758 // FIXME: We end up faking the "parent" declaration here because we
4759 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004760 return MakeCXCursor(getCursorLabelRef(C).first,
4761 cxtu::getASTUnit(tu)->getASTContext()
4762 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 tu);
4764
4765 case CXCursor_OverloadedDeclRef:
4766 return C;
4767
4768 case CXCursor_VariableRef:
4769 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4770
4771 default:
4772 // We would prefer to enumerate all non-reference cursor kinds here.
4773 llvm_unreachable("Unhandled reference cursor kind");
4774 }
4775}
4776
4777CXCursor clang_getCursorDefinition(CXCursor C) {
4778 if (clang_isInvalid(C.kind))
4779 return clang_getNullCursor();
4780
4781 CXTranslationUnit TU = getCursorTU(C);
4782
4783 bool WasReference = false;
4784 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4785 C = clang_getCursorReferenced(C);
4786 WasReference = true;
4787 }
4788
4789 if (C.kind == CXCursor_MacroExpansion)
4790 return clang_getCursorReferenced(C);
4791
4792 if (!clang_isDeclaration(C.kind))
4793 return clang_getNullCursor();
4794
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 if (!D)
4797 return clang_getNullCursor();
4798
4799 switch (D->getKind()) {
4800 // Declaration kinds that don't really separate the notions of
4801 // declaration and definition.
4802 case Decl::Namespace:
4803 case Decl::Typedef:
4804 case Decl::TypeAlias:
4805 case Decl::TypeAliasTemplate:
4806 case Decl::TemplateTypeParm:
4807 case Decl::EnumConstant:
4808 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004809 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 case Decl::IndirectField:
4811 case Decl::ObjCIvar:
4812 case Decl::ObjCAtDefsField:
4813 case Decl::ImplicitParam:
4814 case Decl::ParmVar:
4815 case Decl::NonTypeTemplateParm:
4816 case Decl::TemplateTemplateParm:
4817 case Decl::ObjCCategoryImpl:
4818 case Decl::ObjCImplementation:
4819 case Decl::AccessSpec:
4820 case Decl::LinkageSpec:
4821 case Decl::ObjCPropertyImpl:
4822 case Decl::FileScopeAsm:
4823 case Decl::StaticAssert:
4824 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004825 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 case Decl::Label: // FIXME: Is this right??
4827 case Decl::ClassScopeFunctionSpecialization:
4828 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004829 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 return C;
4831
4832 // Declaration kinds that don't make any sense here, but are
4833 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004834 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 case Decl::TranslationUnit:
4836 break;
4837
4838 // Declaration kinds for which the definition is not resolvable.
4839 case Decl::UnresolvedUsingTypename:
4840 case Decl::UnresolvedUsingValue:
4841 break;
4842
4843 case Decl::UsingDirective:
4844 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4845 TU);
4846
4847 case Decl::NamespaceAlias:
4848 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4849
4850 case Decl::Enum:
4851 case Decl::Record:
4852 case Decl::CXXRecord:
4853 case Decl::ClassTemplateSpecialization:
4854 case Decl::ClassTemplatePartialSpecialization:
4855 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4856 return MakeCXCursor(Def, TU);
4857 return clang_getNullCursor();
4858
4859 case Decl::Function:
4860 case Decl::CXXMethod:
4861 case Decl::CXXConstructor:
4862 case Decl::CXXDestructor:
4863 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004864 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004866 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 return clang_getNullCursor();
4868 }
4869
Larisse Voufo39a1e502013-08-06 01:03:05 +00004870 case Decl::Var:
4871 case Decl::VarTemplateSpecialization:
4872 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 return MakeCXCursor(Def, TU);
4876 return clang_getNullCursor();
4877 }
4878
4879 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004880 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4882 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4883 return clang_getNullCursor();
4884 }
4885
4886 case Decl::ClassTemplate: {
4887 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4888 ->getDefinition())
4889 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4890 TU);
4891 return clang_getNullCursor();
4892 }
4893
Larisse Voufo39a1e502013-08-06 01:03:05 +00004894 case Decl::VarTemplate: {
4895 if (VarDecl *Def =
4896 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4897 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4898 return clang_getNullCursor();
4899 }
4900
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 case Decl::Using:
4902 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4903 D->getLocation(), TU);
4904
4905 case Decl::UsingShadow:
4906 return clang_getCursorDefinition(
4907 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4908 TU));
4909
4910 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 if (Method->isThisDeclarationADefinition())
4913 return C;
4914
4915 // Dig out the method definition in the associated
4916 // @implementation, if we have it.
4917 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004918 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4920 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4921 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4922 Method->isInstanceMethod()))
4923 if (Def->isThisDeclarationADefinition())
4924 return MakeCXCursor(Def, TU);
4925
4926 return clang_getNullCursor();
4927 }
4928
4929 case Decl::ObjCCategory:
4930 if (ObjCCategoryImplDecl *Impl
4931 = cast<ObjCCategoryDecl>(D)->getImplementation())
4932 return MakeCXCursor(Impl, TU);
4933 return clang_getNullCursor();
4934
4935 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004936 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 return MakeCXCursor(Def, TU);
4938 return clang_getNullCursor();
4939
4940 case Decl::ObjCInterface: {
4941 // There are two notions of a "definition" for an Objective-C
4942 // class: the interface and its implementation. When we resolved a
4943 // reference to an Objective-C class, produce the @interface as
4944 // the definition; when we were provided with the interface,
4945 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004948 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 return MakeCXCursor(Def, TU);
4950 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4951 return MakeCXCursor(Impl, TU);
4952 return clang_getNullCursor();
4953 }
4954
4955 case Decl::ObjCProperty:
4956 // FIXME: We don't really know where to find the
4957 // ObjCPropertyImplDecls that implement this property.
4958 return clang_getNullCursor();
4959
4960 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004961 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004963 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 return MakeCXCursor(Def, TU);
4965
4966 return clang_getNullCursor();
4967
4968 case Decl::Friend:
4969 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4970 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4971 return clang_getNullCursor();
4972
4973 case Decl::FriendTemplate:
4974 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4975 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4976 return clang_getNullCursor();
4977 }
4978
4979 return clang_getNullCursor();
4980}
4981
4982unsigned clang_isCursorDefinition(CXCursor C) {
4983 if (!clang_isDeclaration(C.kind))
4984 return 0;
4985
4986 return clang_getCursorDefinition(C) == C;
4987}
4988
4989CXCursor clang_getCanonicalCursor(CXCursor C) {
4990 if (!clang_isDeclaration(C.kind))
4991 return C;
4992
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004993 if (const Decl *D = getCursorDecl(C)) {
4994 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004995 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4996 return MakeCXCursor(CatD, getCursorTU(C));
4997
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004998 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4999 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 return MakeCXCursor(IFD, getCursorTU(C));
5001
5002 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5003 }
5004
5005 return C;
5006}
5007
5008int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5009 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5010}
5011
5012unsigned clang_getNumOverloadedDecls(CXCursor C) {
5013 if (C.kind != CXCursor_OverloadedDeclRef)
5014 return 0;
5015
5016 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005017 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 return E->getNumDecls();
5019
5020 if (OverloadedTemplateStorage *S
5021 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5022 return S->size();
5023
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005024 const Decl *D = Storage.get<const Decl *>();
5025 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 return Using->shadow_size();
5027
5028 return 0;
5029}
5030
5031CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5032 if (cursor.kind != CXCursor_OverloadedDeclRef)
5033 return clang_getNullCursor();
5034
5035 if (index >= clang_getNumOverloadedDecls(cursor))
5036 return clang_getNullCursor();
5037
5038 CXTranslationUnit TU = getCursorTU(cursor);
5039 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005040 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 return MakeCXCursor(E->decls_begin()[index], TU);
5042
5043 if (OverloadedTemplateStorage *S
5044 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5045 return MakeCXCursor(S->begin()[index], TU);
5046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005047 const Decl *D = Storage.get<const Decl *>();
5048 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 // FIXME: This is, unfortunately, linear time.
5050 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5051 std::advance(Pos, index);
5052 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5053 }
5054
5055 return clang_getNullCursor();
5056}
5057
5058void clang_getDefinitionSpellingAndExtent(CXCursor C,
5059 const char **startBuf,
5060 const char **endBuf,
5061 unsigned *startLine,
5062 unsigned *startColumn,
5063 unsigned *endLine,
5064 unsigned *endColumn) {
5065 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005066 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5068
5069 SourceManager &SM = FD->getASTContext().getSourceManager();
5070 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5071 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5072 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5073 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5074 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5075 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5076}
5077
5078
5079CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5080 unsigned PieceIndex) {
5081 RefNamePieces Pieces;
5082
5083 switch (C.kind) {
5084 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005085 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5087 E->getQualifierLoc().getSourceRange());
5088 break;
5089
5090 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005091 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5093 E->getQualifierLoc().getSourceRange(),
5094 E->getOptionalExplicitTemplateArgs());
5095 break;
5096
5097 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005098 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005100 const Expr *Callee = OCE->getCallee();
5101 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 Callee = ICE->getSubExpr();
5103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005104 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5106 DRE->getQualifierLoc().getSourceRange());
5107 }
5108 break;
5109
5110 default:
5111 break;
5112 }
5113
5114 if (Pieces.empty()) {
5115 if (PieceIndex == 0)
5116 return clang_getCursorExtent(C);
5117 } else if (PieceIndex < Pieces.size()) {
5118 SourceRange R = Pieces[PieceIndex];
5119 if (R.isValid())
5120 return cxloc::translateSourceRange(getCursorContext(C), R);
5121 }
5122
5123 return clang_getNullRange();
5124}
5125
5126void clang_enableStackTraces(void) {
5127 llvm::sys::PrintStackTraceOnErrorSignal();
5128}
5129
5130void clang_executeOnThread(void (*fn)(void*), void *user_data,
5131 unsigned stack_size) {
5132 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5133}
5134
5135} // end: extern "C"
5136
5137//===----------------------------------------------------------------------===//
5138// Token-based Operations.
5139//===----------------------------------------------------------------------===//
5140
5141/* CXToken layout:
5142 * int_data[0]: a CXTokenKind
5143 * int_data[1]: starting token location
5144 * int_data[2]: token length
5145 * int_data[3]: reserved
5146 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5147 * otherwise unused.
5148 */
5149extern "C" {
5150
5151CXTokenKind clang_getTokenKind(CXToken CXTok) {
5152 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5153}
5154
5155CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5156 switch (clang_getTokenKind(CXTok)) {
5157 case CXToken_Identifier:
5158 case CXToken_Keyword:
5159 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005160 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 ->getNameStart());
5162
5163 case CXToken_Literal: {
5164 // We have stashed the starting pointer in the ptr_data field. Use it.
5165 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005166 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 }
5168
5169 case CXToken_Punctuation:
5170 case CXToken_Comment:
5171 break;
5172 }
5173
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005174 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005175 LOG_BAD_TU(TU);
5176 return cxstring::createEmpty();
5177 }
5178
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 // We have to find the starting buffer pointer the hard way, by
5180 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005181 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005183 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005184
5185 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5186 std::pair<FileID, unsigned> LocInfo
5187 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5188 bool Invalid = false;
5189 StringRef Buffer
5190 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5191 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005192 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005193
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005194 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005195}
5196
5197CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005198 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005199 LOG_BAD_TU(TU);
5200 return clang_getNullLocation();
5201 }
5202
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005203 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 if (!CXXUnit)
5205 return clang_getNullLocation();
5206
5207 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5208 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5209}
5210
5211CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005212 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005213 LOG_BAD_TU(TU);
5214 return clang_getNullRange();
5215 }
5216
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005217 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 if (!CXXUnit)
5219 return clang_getNullRange();
5220
5221 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5222 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5223}
5224
5225static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5226 SmallVectorImpl<CXToken> &CXTokens) {
5227 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5228 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005229 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005231 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005232
5233 // Cannot tokenize across files.
5234 if (BeginLocInfo.first != EndLocInfo.first)
5235 return;
5236
5237 // Create a lexer
5238 bool Invalid = false;
5239 StringRef Buffer
5240 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5241 if (Invalid)
5242 return;
5243
5244 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5245 CXXUnit->getASTContext().getLangOpts(),
5246 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5247 Lex.SetCommentRetentionState(true);
5248
5249 // Lex tokens until we hit the end of the range.
5250 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5251 Token Tok;
5252 bool previousWasAt = false;
5253 do {
5254 // Lex the next token
5255 Lex.LexFromRawLexer(Tok);
5256 if (Tok.is(tok::eof))
5257 break;
5258
5259 // Initialize the CXToken.
5260 CXToken CXTok;
5261
5262 // - Common fields
5263 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5264 CXTok.int_data[2] = Tok.getLength();
5265 CXTok.int_data[3] = 0;
5266
5267 // - Kind-specific fields
5268 if (Tok.isLiteral()) {
5269 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005270 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 } else if (Tok.is(tok::raw_identifier)) {
5272 // Lookup the identifier to determine whether we have a keyword.
5273 IdentifierInfo *II
5274 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5275
5276 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5277 CXTok.int_data[0] = CXToken_Keyword;
5278 }
5279 else {
5280 CXTok.int_data[0] = Tok.is(tok::identifier)
5281 ? CXToken_Identifier
5282 : CXToken_Keyword;
5283 }
5284 CXTok.ptr_data = II;
5285 } else if (Tok.is(tok::comment)) {
5286 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005287 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 } else {
5289 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005290 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 }
5292 CXTokens.push_back(CXTok);
5293 previousWasAt = Tok.is(tok::at);
5294 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5295}
5296
5297void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5298 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005299 LOG_FUNC_SECTION {
5300 *Log << TU << ' ' << Range;
5301 }
5302
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005304 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 if (NumTokens)
5306 *NumTokens = 0;
5307
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005308 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005309 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005310 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005311 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 if (!CXXUnit || !Tokens || !NumTokens)
5315 return;
5316
5317 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5318
5319 SourceRange R = cxloc::translateCXSourceRange(Range);
5320 if (R.isInvalid())
5321 return;
5322
5323 SmallVector<CXToken, 32> CXTokens;
5324 getTokens(CXXUnit, R, CXTokens);
5325
5326 if (CXTokens.empty())
5327 return;
5328
5329 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5330 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5331 *NumTokens = CXTokens.size();
5332}
5333
5334void clang_disposeTokens(CXTranslationUnit TU,
5335 CXToken *Tokens, unsigned NumTokens) {
5336 free(Tokens);
5337}
5338
5339} // end: extern "C"
5340
5341//===----------------------------------------------------------------------===//
5342// Token annotation APIs.
5343//===----------------------------------------------------------------------===//
5344
Guy Benyei11169dd2012-12-18 14:30:41 +00005345static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5346 CXCursor parent,
5347 CXClientData client_data);
5348static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5349 CXClientData client_data);
5350
5351namespace {
5352class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 CXToken *Tokens;
5354 CXCursor *Cursors;
5355 unsigned NumTokens;
5356 unsigned TokIdx;
5357 unsigned PreprocessingTokIdx;
5358 CursorVisitor AnnotateVis;
5359 SourceManager &SrcMgr;
5360 bool HasContextSensitiveKeywords;
5361
5362 struct PostChildrenInfo {
5363 CXCursor Cursor;
5364 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005365 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 unsigned BeforeChildrenTokenIdx;
5367 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005368 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005369
5370 CXToken &getTok(unsigned Idx) {
5371 assert(Idx < NumTokens);
5372 return Tokens[Idx];
5373 }
5374 const CXToken &getTok(unsigned Idx) const {
5375 assert(Idx < NumTokens);
5376 return Tokens[Idx];
5377 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 bool MoreTokens() const { return TokIdx < NumTokens; }
5379 unsigned NextToken() const { return TokIdx; }
5380 void AdvanceToken() { ++TokIdx; }
5381 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005382 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 }
5384 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005385 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 }
5387 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005388 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 }
5390
5391 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005392 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 SourceRange);
5394
5395public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005396 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005397 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005398 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005400 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 AnnotateTokensVisitor, this,
5402 /*VisitPreprocessorLast=*/true,
5403 /*VisitIncludedEntities=*/false,
5404 RegionOfInterest,
5405 /*VisitDeclsOnly=*/false,
5406 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005407 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 HasContextSensitiveKeywords(false) { }
5409
5410 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5411 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5412 bool postVisitChildren(CXCursor cursor);
5413 void AnnotateTokens();
5414
5415 /// \brief Determine whether the annotator saw any cursors that have
5416 /// context-sensitive keywords.
5417 bool hasContextSensitiveKeywords() const {
5418 return HasContextSensitiveKeywords;
5419 }
5420
5421 ~AnnotateTokensWorker() {
5422 assert(PostChildrenInfos.empty());
5423 }
5424};
5425}
5426
5427void AnnotateTokensWorker::AnnotateTokens() {
5428 // Walk the AST within the region of interest, annotating tokens
5429 // along the way.
5430 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005431}
Guy Benyei11169dd2012-12-18 14:30:41 +00005432
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005433static inline void updateCursorAnnotation(CXCursor &Cursor,
5434 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005435 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005437 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005438}
5439
5440/// \brief It annotates and advances tokens with a cursor until the comparison
5441//// between the cursor location and the source range is the same as
5442/// \arg compResult.
5443///
5444/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5445/// Pass RangeOverlap to annotate tokens inside a range.
5446void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5447 RangeComparisonResult compResult,
5448 SourceRange range) {
5449 while (MoreTokens()) {
5450 const unsigned I = NextToken();
5451 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005452 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5453 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005454
5455 SourceLocation TokLoc = GetTokenLoc(I);
5456 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005457 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 AdvanceToken();
5459 continue;
5460 }
5461 break;
5462 }
5463}
5464
5465/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005466/// \returns true if it advanced beyond all macro tokens, false otherwise.
5467bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 CXCursor updateC,
5469 RangeComparisonResult compResult,
5470 SourceRange range) {
5471 assert(MoreTokens());
5472 assert(isFunctionMacroToken(NextToken()) &&
5473 "Should be called only for macro arg tokens");
5474
5475 // This works differently than annotateAndAdvanceTokens; because expanded
5476 // macro arguments can have arbitrary translation-unit source order, we do not
5477 // advance the token index one by one until a token fails the range test.
5478 // We only advance once past all of the macro arg tokens if all of them
5479 // pass the range test. If one of them fails we keep the token index pointing
5480 // at the start of the macro arg tokens so that the failing token will be
5481 // annotated by a subsequent annotation try.
5482
5483 bool atLeastOneCompFail = false;
5484
5485 unsigned I = NextToken();
5486 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5487 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5488 if (TokLoc.isFileID())
5489 continue; // not macro arg token, it's parens or comma.
5490 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5491 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5492 Cursors[I] = updateC;
5493 } else
5494 atLeastOneCompFail = true;
5495 }
5496
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005497 if (atLeastOneCompFail)
5498 return false;
5499
5500 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5501 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005502}
5503
5504enum CXChildVisitResult
5505AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 SourceRange cursorRange = getRawCursorExtent(cursor);
5507 if (cursorRange.isInvalid())
5508 return CXChildVisit_Recurse;
5509
5510 if (!HasContextSensitiveKeywords) {
5511 // Objective-C properties can have context-sensitive keywords.
5512 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005513 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5515 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5516 }
5517 // Objective-C methods can have context-sensitive keywords.
5518 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5519 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005520 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5522 if (Method->getObjCDeclQualifier())
5523 HasContextSensitiveKeywords = true;
5524 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005525 for (const auto *P : Method->params()) {
5526 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 HasContextSensitiveKeywords = true;
5528 break;
5529 }
5530 }
5531 }
5532 }
5533 }
5534 // C++ methods can have context-sensitive keywords.
5535 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005536 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005537 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5538 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5539 HasContextSensitiveKeywords = true;
5540 }
5541 }
5542 // C++ classes can have context-sensitive keywords.
5543 else if (cursor.kind == CXCursor_StructDecl ||
5544 cursor.kind == CXCursor_ClassDecl ||
5545 cursor.kind == CXCursor_ClassTemplate ||
5546 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005547 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 if (D->hasAttr<FinalAttr>())
5549 HasContextSensitiveKeywords = true;
5550 }
5551 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005552
5553 // Don't override a property annotation with its getter/setter method.
5554 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5555 parent.kind == CXCursor_ObjCPropertyDecl)
5556 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005557
5558 if (clang_isPreprocessing(cursor.kind)) {
5559 // Items in the preprocessing record are kept separate from items in
5560 // declarations, so we keep a separate token index.
5561 unsigned SavedTokIdx = TokIdx;
5562 TokIdx = PreprocessingTokIdx;
5563
5564 // Skip tokens up until we catch up to the beginning of the preprocessing
5565 // entry.
5566 while (MoreTokens()) {
5567 const unsigned I = NextToken();
5568 SourceLocation TokLoc = GetTokenLoc(I);
5569 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5570 case RangeBefore:
5571 AdvanceToken();
5572 continue;
5573 case RangeAfter:
5574 case RangeOverlap:
5575 break;
5576 }
5577 break;
5578 }
5579
5580 // Look at all of the tokens within this range.
5581 while (MoreTokens()) {
5582 const unsigned I = NextToken();
5583 SourceLocation TokLoc = GetTokenLoc(I);
5584 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5585 case RangeBefore:
5586 llvm_unreachable("Infeasible");
5587 case RangeAfter:
5588 break;
5589 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005590 // For macro expansions, just note where the beginning of the macro
5591 // expansion occurs.
5592 if (cursor.kind == CXCursor_MacroExpansion) {
5593 if (TokLoc == cursorRange.getBegin())
5594 Cursors[I] = cursor;
5595 AdvanceToken();
5596 break;
5597 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005598 // We may have already annotated macro names inside macro definitions.
5599 if (Cursors[I].kind != CXCursor_MacroExpansion)
5600 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 continue;
5603 }
5604 break;
5605 }
5606
5607 // Save the preprocessing token index; restore the non-preprocessing
5608 // token index.
5609 PreprocessingTokIdx = TokIdx;
5610 TokIdx = SavedTokIdx;
5611 return CXChildVisit_Recurse;
5612 }
5613
5614 if (cursorRange.isInvalid())
5615 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005616
5617 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 const enum CXCursorKind K = clang_getCursorKind(parent);
5620 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005621 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5622 // Attributes are annotated out-of-order, skip tokens until we reach it.
5623 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 ? clang_getNullCursor() : parent;
5625
5626 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5627
5628 // Avoid having the cursor of an expression "overwrite" the annotation of the
5629 // variable declaration that it belongs to.
5630 // This can happen for C++ constructor expressions whose range generally
5631 // include the variable declaration, e.g.:
5632 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005633 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005634 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005635 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 const unsigned I = NextToken();
5637 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5638 E->getLocStart() == D->getLocation() &&
5639 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005640 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 AdvanceToken();
5642 }
5643 }
5644 }
5645
5646 // Before recursing into the children keep some state that we are going
5647 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5648 // extra work after the child nodes are visited.
5649 // Note that we don't call VisitChildren here to avoid traversing statements
5650 // code-recursively which can blow the stack.
5651
5652 PostChildrenInfo Info;
5653 Info.Cursor = cursor;
5654 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005655 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 Info.BeforeChildrenTokenIdx = NextToken();
5657 PostChildrenInfos.push_back(Info);
5658
5659 return CXChildVisit_Recurse;
5660}
5661
5662bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5663 if (PostChildrenInfos.empty())
5664 return false;
5665 const PostChildrenInfo &Info = PostChildrenInfos.back();
5666 if (!clang_equalCursors(Info.Cursor, cursor))
5667 return false;
5668
5669 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5670 const unsigned AfterChildren = NextToken();
5671 SourceRange cursorRange = Info.CursorRange;
5672
5673 // Scan the tokens that are at the end of the cursor, but are not captured
5674 // but the child cursors.
5675 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5676
5677 // Scan the tokens that are at the beginning of the cursor, but are not
5678 // capture by the child cursors.
5679 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5680 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5681 break;
5682
5683 Cursors[I] = cursor;
5684 }
5685
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005686 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5687 // encountered the attribute cursor.
5688 if (clang_isAttribute(cursor.kind))
5689 TokIdx = Info.BeforeReachingCursorIdx;
5690
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 PostChildrenInfos.pop_back();
5692 return false;
5693}
5694
5695static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5696 CXCursor parent,
5697 CXClientData client_data) {
5698 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5699}
5700
5701static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5702 CXClientData client_data) {
5703 return static_cast<AnnotateTokensWorker*>(client_data)->
5704 postVisitChildren(cursor);
5705}
5706
5707namespace {
5708
5709/// \brief Uses the macro expansions in the preprocessing record to find
5710/// and mark tokens that are macro arguments. This info is used by the
5711/// AnnotateTokensWorker.
5712class MarkMacroArgTokensVisitor {
5713 SourceManager &SM;
5714 CXToken *Tokens;
5715 unsigned NumTokens;
5716 unsigned CurIdx;
5717
5718public:
5719 MarkMacroArgTokensVisitor(SourceManager &SM,
5720 CXToken *tokens, unsigned numTokens)
5721 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5722
5723 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5724 if (cursor.kind != CXCursor_MacroExpansion)
5725 return CXChildVisit_Continue;
5726
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005727 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 if (macroRange.getBegin() == macroRange.getEnd())
5729 return CXChildVisit_Continue; // it's not a function macro.
5730
5731 for (; CurIdx < NumTokens; ++CurIdx) {
5732 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5733 macroRange.getBegin()))
5734 break;
5735 }
5736
5737 if (CurIdx == NumTokens)
5738 return CXChildVisit_Break;
5739
5740 for (; CurIdx < NumTokens; ++CurIdx) {
5741 SourceLocation tokLoc = getTokenLoc(CurIdx);
5742 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5743 break;
5744
5745 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5746 }
5747
5748 if (CurIdx == NumTokens)
5749 return CXChildVisit_Break;
5750
5751 return CXChildVisit_Continue;
5752 }
5753
5754private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005755 CXToken &getTok(unsigned Idx) {
5756 assert(Idx < NumTokens);
5757 return Tokens[Idx];
5758 }
5759 const CXToken &getTok(unsigned Idx) const {
5760 assert(Idx < NumTokens);
5761 return Tokens[Idx];
5762 }
5763
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005765 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 }
5767
5768 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5769 // The third field is reserved and currently not used. Use it here
5770 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005771 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 }
5773};
5774
5775} // end anonymous namespace
5776
5777static CXChildVisitResult
5778MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5779 CXClientData client_data) {
5780 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5781 parent);
5782}
5783
5784namespace {
5785 struct clang_annotateTokens_Data {
5786 CXTranslationUnit TU;
5787 ASTUnit *CXXUnit;
5788 CXToken *Tokens;
5789 unsigned NumTokens;
5790 CXCursor *Cursors;
5791 };
5792}
5793
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005794/// \brief Used by \c annotatePreprocessorTokens.
5795/// \returns true if lexing was finished, false otherwise.
5796static bool lexNext(Lexer &Lex, Token &Tok,
5797 unsigned &NextIdx, unsigned NumTokens) {
5798 if (NextIdx >= NumTokens)
5799 return true;
5800
5801 ++NextIdx;
5802 Lex.LexFromRawLexer(Tok);
5803 if (Tok.is(tok::eof))
5804 return true;
5805
5806 return false;
5807}
5808
Guy Benyei11169dd2012-12-18 14:30:41 +00005809static void annotatePreprocessorTokens(CXTranslationUnit TU,
5810 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005811 CXCursor *Cursors,
5812 CXToken *Tokens,
5813 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005814 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005815
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005816 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005817 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5818 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005819 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005821 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005822
5823 if (BeginLocInfo.first != EndLocInfo.first)
5824 return;
5825
5826 StringRef Buffer;
5827 bool Invalid = false;
5828 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5829 if (Buffer.empty() || Invalid)
5830 return;
5831
5832 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5833 CXXUnit->getASTContext().getLangOpts(),
5834 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5835 Buffer.end());
5836 Lex.SetCommentRetentionState(true);
5837
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005838 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 // Lex tokens in raw mode until we hit the end of the range, to avoid
5840 // entering #includes or expanding macros.
5841 while (true) {
5842 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005843 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5844 break;
5845 unsigned TokIdx = NextIdx-1;
5846 assert(Tok.getLocation() ==
5847 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005848
5849 reprocess:
5850 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005851 // We have found a preprocessing directive. Annotate the tokens
5852 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 //
5854 // FIXME: Some simple tests here could identify macro definitions and
5855 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005856
5857 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005858 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5859 break;
5860
Craig Topper69186e72014-06-08 08:38:04 +00005861 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005862 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005863 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5864 break;
5865
5866 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005867 IdentifierInfo &II =
5868 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005869 SourceLocation MappedTokLoc =
5870 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5871 MI = getMacroInfo(II, MappedTokLoc, TU);
5872 }
5873 }
5874
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005875 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005877 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5878 finished = true;
5879 break;
5880 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005881 // If we are in a macro definition, check if the token was ever a
5882 // macro name and annotate it if that's the case.
5883 if (MI) {
5884 SourceLocation SaveLoc = Tok.getLocation();
5885 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5886 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5887 Tok.setLocation(SaveLoc);
5888 if (MacroDef)
5889 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5890 Tok.getLocation(), TU);
5891 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005892 } while (!Tok.isAtStartOfLine());
5893
5894 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5895 assert(TokIdx <= LastIdx);
5896 SourceLocation EndLoc =
5897 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5898 CXCursor Cursor =
5899 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5900
5901 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005902 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005903
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005904 if (finished)
5905 break;
5906 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 }
5909}
5910
5911// This gets run a separate thread to avoid stack blowout.
5912static void clang_annotateTokensImpl(void *UserData) {
5913 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5914 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5915 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5916 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5917 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5918
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005919 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5921 setThreadBackgroundPriority();
5922
5923 // Determine the region of interest, which contains all of the tokens.
5924 SourceRange RegionOfInterest;
5925 RegionOfInterest.setBegin(
5926 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5927 RegionOfInterest.setEnd(
5928 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5929 Tokens[NumTokens-1])));
5930
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 // Relex the tokens within the source range to look for preprocessing
5932 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005933 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005934
5935 // If begin location points inside a macro argument, set it to the expansion
5936 // location so we can have the full context when annotating semantically.
5937 {
5938 SourceManager &SM = CXXUnit->getSourceManager();
5939 SourceLocation Loc =
5940 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5941 if (Loc.isMacroID())
5942 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5943 }
5944
Guy Benyei11169dd2012-12-18 14:30:41 +00005945 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5946 // Search and mark tokens that are macro argument expansions.
5947 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5948 Tokens, NumTokens);
5949 CursorVisitor MacroArgMarker(TU,
5950 MarkMacroArgTokensVisitorDelegate, &Visitor,
5951 /*VisitPreprocessorLast=*/true,
5952 /*VisitIncludedEntities=*/false,
5953 RegionOfInterest);
5954 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5955 }
5956
5957 // Annotate all of the source locations in the region of interest that map to
5958 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005959 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005960
5961 // FIXME: We use a ridiculous stack size here because the data-recursion
5962 // algorithm uses a large stack frame than the non-data recursive version,
5963 // and AnnotationTokensWorker currently transforms the data-recursion
5964 // algorithm back into a traditional recursion by explicitly calling
5965 // VisitChildren(). We will need to remove this explicit recursive call.
5966 W.AnnotateTokens();
5967
5968 // If we ran into any entities that involve context-sensitive keywords,
5969 // take another pass through the tokens to mark them as such.
5970 if (W.hasContextSensitiveKeywords()) {
5971 for (unsigned I = 0; I != NumTokens; ++I) {
5972 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5973 continue;
5974
5975 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5976 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005977 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5979 if (Property->getPropertyAttributesAsWritten() != 0 &&
5980 llvm::StringSwitch<bool>(II->getName())
5981 .Case("readonly", true)
5982 .Case("assign", true)
5983 .Case("unsafe_unretained", true)
5984 .Case("readwrite", true)
5985 .Case("retain", true)
5986 .Case("copy", true)
5987 .Case("nonatomic", true)
5988 .Case("atomic", true)
5989 .Case("getter", true)
5990 .Case("setter", true)
5991 .Case("strong", true)
5992 .Case("weak", true)
5993 .Default(false))
5994 Tokens[I].int_data[0] = CXToken_Keyword;
5995 }
5996 continue;
5997 }
5998
5999 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6000 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6001 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6002 if (llvm::StringSwitch<bool>(II->getName())
6003 .Case("in", true)
6004 .Case("out", true)
6005 .Case("inout", true)
6006 .Case("oneway", true)
6007 .Case("bycopy", true)
6008 .Case("byref", true)
6009 .Default(false))
6010 Tokens[I].int_data[0] = CXToken_Keyword;
6011 continue;
6012 }
6013
6014 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6015 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6016 Tokens[I].int_data[0] = CXToken_Keyword;
6017 continue;
6018 }
6019 }
6020 }
6021}
6022
6023extern "C" {
6024
6025void clang_annotateTokens(CXTranslationUnit TU,
6026 CXToken *Tokens, unsigned NumTokens,
6027 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006028 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006029 LOG_BAD_TU(TU);
6030 return;
6031 }
6032 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006033 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006035 }
6036
6037 LOG_FUNC_SECTION {
6038 *Log << TU << ' ';
6039 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6040 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6041 *Log << clang_getRange(bloc, eloc);
6042 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006043
6044 // Any token we don't specifically annotate will have a NULL cursor.
6045 CXCursor C = clang_getNullCursor();
6046 for (unsigned I = 0; I != NumTokens; ++I)
6047 Cursors[I] = C;
6048
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006049 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 if (!CXXUnit)
6051 return;
6052
6053 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6054
6055 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6056 llvm::CrashRecoveryContext CRC;
6057 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6058 GetSafetyThreadStackSize() * 2)) {
6059 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6060 }
6061}
6062
6063} // end: extern "C"
6064
6065//===----------------------------------------------------------------------===//
6066// Operations for querying linkage of a cursor.
6067//===----------------------------------------------------------------------===//
6068
6069extern "C" {
6070CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6071 if (!clang_isDeclaration(cursor.kind))
6072 return CXLinkage_Invalid;
6073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006074 const Decl *D = cxcursor::getCursorDecl(cursor);
6075 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006076 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006077 case NoLinkage:
6078 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006079 case InternalLinkage: return CXLinkage_Internal;
6080 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6081 case ExternalLinkage: return CXLinkage_External;
6082 };
6083
6084 return CXLinkage_Invalid;
6085}
6086} // end: extern "C"
6087
6088//===----------------------------------------------------------------------===//
6089// Operations for querying language of a cursor.
6090//===----------------------------------------------------------------------===//
6091
6092static CXLanguageKind getDeclLanguage(const Decl *D) {
6093 if (!D)
6094 return CXLanguage_C;
6095
6096 switch (D->getKind()) {
6097 default:
6098 break;
6099 case Decl::ImplicitParam:
6100 case Decl::ObjCAtDefsField:
6101 case Decl::ObjCCategory:
6102 case Decl::ObjCCategoryImpl:
6103 case Decl::ObjCCompatibleAlias:
6104 case Decl::ObjCImplementation:
6105 case Decl::ObjCInterface:
6106 case Decl::ObjCIvar:
6107 case Decl::ObjCMethod:
6108 case Decl::ObjCProperty:
6109 case Decl::ObjCPropertyImpl:
6110 case Decl::ObjCProtocol:
6111 return CXLanguage_ObjC;
6112 case Decl::CXXConstructor:
6113 case Decl::CXXConversion:
6114 case Decl::CXXDestructor:
6115 case Decl::CXXMethod:
6116 case Decl::CXXRecord:
6117 case Decl::ClassTemplate:
6118 case Decl::ClassTemplatePartialSpecialization:
6119 case Decl::ClassTemplateSpecialization:
6120 case Decl::Friend:
6121 case Decl::FriendTemplate:
6122 case Decl::FunctionTemplate:
6123 case Decl::LinkageSpec:
6124 case Decl::Namespace:
6125 case Decl::NamespaceAlias:
6126 case Decl::NonTypeTemplateParm:
6127 case Decl::StaticAssert:
6128 case Decl::TemplateTemplateParm:
6129 case Decl::TemplateTypeParm:
6130 case Decl::UnresolvedUsingTypename:
6131 case Decl::UnresolvedUsingValue:
6132 case Decl::Using:
6133 case Decl::UsingDirective:
6134 case Decl::UsingShadow:
6135 return CXLanguage_CPlusPlus;
6136 }
6137
6138 return CXLanguage_C;
6139}
6140
6141extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006142
6143static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6144 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6145 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006146
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006147 switch (D->getAvailability()) {
6148 case AR_Available:
6149 case AR_NotYetIntroduced:
6150 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006151 return getCursorAvailabilityForDecl(
6152 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006153 return CXAvailability_Available;
6154
6155 case AR_Deprecated:
6156 return CXAvailability_Deprecated;
6157
6158 case AR_Unavailable:
6159 return CXAvailability_NotAvailable;
6160 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006161
6162 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006163}
6164
Guy Benyei11169dd2012-12-18 14:30:41 +00006165enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6166 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006167 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6168 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006169
6170 return CXAvailability_Available;
6171}
6172
6173static CXVersion convertVersion(VersionTuple In) {
6174 CXVersion Out = { -1, -1, -1 };
6175 if (In.empty())
6176 return Out;
6177
6178 Out.Major = In.getMajor();
6179
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006180 Optional<unsigned> Minor = In.getMinor();
6181 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 Out.Minor = *Minor;
6183 else
6184 return Out;
6185
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006186 Optional<unsigned> Subminor = In.getSubminor();
6187 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 Out.Subminor = *Subminor;
6189
6190 return Out;
6191}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006192
6193static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6194 int *always_deprecated,
6195 CXString *deprecated_message,
6196 int *always_unavailable,
6197 CXString *unavailable_message,
6198 CXPlatformAvailability *availability,
6199 int availability_size) {
6200 bool HadAvailAttr = false;
6201 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006202 for (auto A : D->attrs()) {
6203 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006204 HadAvailAttr = true;
6205 if (always_deprecated)
6206 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006207 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006208 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006209 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006210 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006211 continue;
6212 }
6213
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006214 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006215 HadAvailAttr = true;
6216 if (always_unavailable)
6217 *always_unavailable = 1;
6218 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006219 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006220 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6221 }
6222 continue;
6223 }
6224
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006225 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006226 HadAvailAttr = true;
6227 if (N < availability_size) {
6228 availability[N].Platform
6229 = cxstring::createDup(Avail->getPlatform()->getName());
6230 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6231 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6232 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6233 availability[N].Unavailable = Avail->getUnavailable();
6234 availability[N].Message = cxstring::createDup(Avail->getMessage());
6235 }
6236 ++N;
6237 }
6238 }
6239
6240 if (!HadAvailAttr)
6241 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6242 return getCursorPlatformAvailabilityForDecl(
6243 cast<Decl>(EnumConst->getDeclContext()),
6244 always_deprecated,
6245 deprecated_message,
6246 always_unavailable,
6247 unavailable_message,
6248 availability,
6249 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006250
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006251 return N;
6252}
6253
Guy Benyei11169dd2012-12-18 14:30:41 +00006254int clang_getCursorPlatformAvailability(CXCursor cursor,
6255 int *always_deprecated,
6256 CXString *deprecated_message,
6257 int *always_unavailable,
6258 CXString *unavailable_message,
6259 CXPlatformAvailability *availability,
6260 int availability_size) {
6261 if (always_deprecated)
6262 *always_deprecated = 0;
6263 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006264 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006265 if (always_unavailable)
6266 *always_unavailable = 0;
6267 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006268 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006269
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 if (!clang_isDeclaration(cursor.kind))
6271 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006272
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006273 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006274 if (!D)
6275 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006276
6277 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6278 deprecated_message,
6279 always_unavailable,
6280 unavailable_message,
6281 availability,
6282 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006283}
6284
6285void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6286 clang_disposeString(availability->Platform);
6287 clang_disposeString(availability->Message);
6288}
6289
6290CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6291 if (clang_isDeclaration(cursor.kind))
6292 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6293
6294 return CXLanguage_Invalid;
6295}
6296
6297 /// \brief If the given cursor is the "templated" declaration
6298 /// descibing a class or function template, return the class or
6299 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006300static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006302 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006304 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006305 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6306 return FunTmpl;
6307
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006308 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6310 return ClassTmpl;
6311
6312 return D;
6313}
6314
6315CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6316 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006317 if (const Decl *D = getCursorDecl(cursor)) {
6318 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 if (!DC)
6320 return clang_getNullCursor();
6321
6322 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6323 getCursorTU(cursor));
6324 }
6325 }
6326
6327 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006328 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006329 return MakeCXCursor(D, getCursorTU(cursor));
6330 }
6331
6332 return clang_getNullCursor();
6333}
6334
6335CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6336 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006337 if (const Decl *D = getCursorDecl(cursor)) {
6338 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 if (!DC)
6340 return clang_getNullCursor();
6341
6342 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6343 getCursorTU(cursor));
6344 }
6345 }
6346
6347 // FIXME: Note that we can't easily compute the lexical context of a
6348 // statement or expression, so we return nothing.
6349 return clang_getNullCursor();
6350}
6351
6352CXFile clang_getIncludedFile(CXCursor cursor) {
6353 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006354 return nullptr;
6355
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006356 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006357 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006358}
6359
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006360unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6361 if (C.kind != CXCursor_ObjCPropertyDecl)
6362 return CXObjCPropertyAttr_noattr;
6363
6364 unsigned Result = CXObjCPropertyAttr_noattr;
6365 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6366 ObjCPropertyDecl::PropertyAttributeKind Attr =
6367 PD->getPropertyAttributesAsWritten();
6368
6369#define SET_CXOBJCPROP_ATTR(A) \
6370 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6371 Result |= CXObjCPropertyAttr_##A
6372 SET_CXOBJCPROP_ATTR(readonly);
6373 SET_CXOBJCPROP_ATTR(getter);
6374 SET_CXOBJCPROP_ATTR(assign);
6375 SET_CXOBJCPROP_ATTR(readwrite);
6376 SET_CXOBJCPROP_ATTR(retain);
6377 SET_CXOBJCPROP_ATTR(copy);
6378 SET_CXOBJCPROP_ATTR(nonatomic);
6379 SET_CXOBJCPROP_ATTR(setter);
6380 SET_CXOBJCPROP_ATTR(atomic);
6381 SET_CXOBJCPROP_ATTR(weak);
6382 SET_CXOBJCPROP_ATTR(strong);
6383 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6384#undef SET_CXOBJCPROP_ATTR
6385
6386 return Result;
6387}
6388
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006389unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6390 if (!clang_isDeclaration(C.kind))
6391 return CXObjCDeclQualifier_None;
6392
6393 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6394 const Decl *D = getCursorDecl(C);
6395 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6396 QT = MD->getObjCDeclQualifier();
6397 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6398 QT = PD->getObjCDeclQualifier();
6399 if (QT == Decl::OBJC_TQ_None)
6400 return CXObjCDeclQualifier_None;
6401
6402 unsigned Result = CXObjCDeclQualifier_None;
6403 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6404 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6405 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6406 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6407 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6408 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6409
6410 return Result;
6411}
6412
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006413unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6414 if (!clang_isDeclaration(C.kind))
6415 return 0;
6416
6417 const Decl *D = getCursorDecl(C);
6418 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6419 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6420 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6421 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6422
6423 return 0;
6424}
6425
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006426unsigned clang_Cursor_isVariadic(CXCursor C) {
6427 if (!clang_isDeclaration(C.kind))
6428 return 0;
6429
6430 const Decl *D = getCursorDecl(C);
6431 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6432 return FD->isVariadic();
6433 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6434 return MD->isVariadic();
6435
6436 return 0;
6437}
6438
Guy Benyei11169dd2012-12-18 14:30:41 +00006439CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6440 if (!clang_isDeclaration(C.kind))
6441 return clang_getNullRange();
6442
6443 const Decl *D = getCursorDecl(C);
6444 ASTContext &Context = getCursorContext(C);
6445 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6446 if (!RC)
6447 return clang_getNullRange();
6448
6449 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6450}
6451
6452CXString clang_Cursor_getRawCommentText(CXCursor C) {
6453 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006454 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006455
6456 const Decl *D = getCursorDecl(C);
6457 ASTContext &Context = getCursorContext(C);
6458 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6459 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6460 StringRef();
6461
6462 // Don't duplicate the string because RawText points directly into source
6463 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006464 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006465}
6466
6467CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6468 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006469 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006470
6471 const Decl *D = getCursorDecl(C);
6472 const ASTContext &Context = getCursorContext(C);
6473 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6474
6475 if (RC) {
6476 StringRef BriefText = RC->getBriefText(Context);
6477
6478 // Don't duplicate the string because RawComment ensures that this memory
6479 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006480 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 }
6482
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006483 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006484}
6485
Guy Benyei11169dd2012-12-18 14:30:41 +00006486CXModule clang_Cursor_getModule(CXCursor C) {
6487 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006488 if (const ImportDecl *ImportD =
6489 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006490 return ImportD->getImportedModule();
6491 }
6492
Craig Topper69186e72014-06-08 08:38:04 +00006493 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006494}
6495
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006496CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6497 if (isNotUsableTU(TU)) {
6498 LOG_BAD_TU(TU);
6499 return nullptr;
6500 }
6501 if (!File)
6502 return nullptr;
6503 FileEntry *FE = static_cast<FileEntry *>(File);
6504
6505 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6506 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6507 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6508
6509 if (Module *Mod = Header.getModule()) {
6510 if (Header.getRole() != ModuleMap::ExcludedHeader)
6511 return Mod;
6512 }
6513 return nullptr;
6514}
6515
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006516CXFile clang_Module_getASTFile(CXModule CXMod) {
6517 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006518 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006519 Module *Mod = static_cast<Module*>(CXMod);
6520 return const_cast<FileEntry *>(Mod->getASTFile());
6521}
6522
Guy Benyei11169dd2012-12-18 14:30:41 +00006523CXModule clang_Module_getParent(CXModule CXMod) {
6524 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006525 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 Module *Mod = static_cast<Module*>(CXMod);
6527 return Mod->Parent;
6528}
6529
6530CXString clang_Module_getName(CXModule CXMod) {
6531 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006532 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006533 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006534 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006535}
6536
6537CXString clang_Module_getFullName(CXModule CXMod) {
6538 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006539 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006541 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006542}
6543
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006544int clang_Module_isSystem(CXModule CXMod) {
6545 if (!CXMod)
6546 return 0;
6547 Module *Mod = static_cast<Module*>(CXMod);
6548 return Mod->IsSystem;
6549}
6550
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006551unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6552 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006553 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006554 LOG_BAD_TU(TU);
6555 return 0;
6556 }
6557 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 return 0;
6559 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006560 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6561 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6562 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006563}
6564
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006565CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6566 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006567 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006568 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006569 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006570 }
6571 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006572 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006574 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006575
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006576 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6577 if (Index < TopHeaders.size())
6578 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006579
Craig Topper69186e72014-06-08 08:38:04 +00006580 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006581}
6582
6583} // end: extern "C"
6584
6585//===----------------------------------------------------------------------===//
6586// C++ AST instrospection.
6587//===----------------------------------------------------------------------===//
6588
6589extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006590unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6591 if (!clang_isDeclaration(C.kind))
6592 return 0;
6593
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006594 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006595 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006596 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006597 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6598}
6599
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006600unsigned clang_CXXMethod_isConst(CXCursor C) {
6601 if (!clang_isDeclaration(C.kind))
6602 return 0;
6603
6604 const Decl *D = cxcursor::getCursorDecl(C);
6605 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006606 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006607 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6608}
6609
Guy Benyei11169dd2012-12-18 14:30:41 +00006610unsigned clang_CXXMethod_isStatic(CXCursor C) {
6611 if (!clang_isDeclaration(C.kind))
6612 return 0;
6613
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006614 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006615 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006616 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 return (Method && Method->isStatic()) ? 1 : 0;
6618}
6619
6620unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6621 if (!clang_isDeclaration(C.kind))
6622 return 0;
6623
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006624 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006625 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006626 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 return (Method && Method->isVirtual()) ? 1 : 0;
6628}
6629} // end: extern "C"
6630
6631//===----------------------------------------------------------------------===//
6632// Attribute introspection.
6633//===----------------------------------------------------------------------===//
6634
6635extern "C" {
6636CXType clang_getIBOutletCollectionType(CXCursor C) {
6637 if (C.kind != CXCursor_IBOutletCollectionAttr)
6638 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6639
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006640 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006641 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6642
6643 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6644}
6645} // end: extern "C"
6646
6647//===----------------------------------------------------------------------===//
6648// Inspecting memory usage.
6649//===----------------------------------------------------------------------===//
6650
6651typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6652
6653static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6654 enum CXTUResourceUsageKind k,
6655 unsigned long amount) {
6656 CXTUResourceUsageEntry entry = { k, amount };
6657 entries.push_back(entry);
6658}
6659
6660extern "C" {
6661
6662const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6663 const char *str = "";
6664 switch (kind) {
6665 case CXTUResourceUsage_AST:
6666 str = "ASTContext: expressions, declarations, and types";
6667 break;
6668 case CXTUResourceUsage_Identifiers:
6669 str = "ASTContext: identifiers";
6670 break;
6671 case CXTUResourceUsage_Selectors:
6672 str = "ASTContext: selectors";
6673 break;
6674 case CXTUResourceUsage_GlobalCompletionResults:
6675 str = "Code completion: cached global results";
6676 break;
6677 case CXTUResourceUsage_SourceManagerContentCache:
6678 str = "SourceManager: content cache allocator";
6679 break;
6680 case CXTUResourceUsage_AST_SideTables:
6681 str = "ASTContext: side tables";
6682 break;
6683 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6684 str = "SourceManager: malloc'ed memory buffers";
6685 break;
6686 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6687 str = "SourceManager: mmap'ed memory buffers";
6688 break;
6689 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6690 str = "ExternalASTSource: malloc'ed memory buffers";
6691 break;
6692 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6693 str = "ExternalASTSource: mmap'ed memory buffers";
6694 break;
6695 case CXTUResourceUsage_Preprocessor:
6696 str = "Preprocessor: malloc'ed memory";
6697 break;
6698 case CXTUResourceUsage_PreprocessingRecord:
6699 str = "Preprocessor: PreprocessingRecord";
6700 break;
6701 case CXTUResourceUsage_SourceManager_DataStructures:
6702 str = "SourceManager: data structures and tables";
6703 break;
6704 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6705 str = "Preprocessor: header search tables";
6706 break;
6707 }
6708 return str;
6709}
6710
6711CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006712 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006713 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006714 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006715 return usage;
6716 }
6717
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006718 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006719 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 ASTContext &astContext = astUnit->getASTContext();
6721
6722 // How much memory is used by AST nodes and types?
6723 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6724 (unsigned long) astContext.getASTAllocatedMemory());
6725
6726 // How much memory is used by identifiers?
6727 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6728 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6729
6730 // How much memory is used for selectors?
6731 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6732 (unsigned long) astContext.Selectors.getTotalMemory());
6733
6734 // How much memory is used by ASTContext's side tables?
6735 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6736 (unsigned long) astContext.getSideTableAllocatedMemory());
6737
6738 // How much memory is used for caching global code completion results?
6739 unsigned long completionBytes = 0;
6740 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006741 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006742 completionBytes = completionAllocator->getTotalMemory();
6743 }
6744 createCXTUResourceUsageEntry(*entries,
6745 CXTUResourceUsage_GlobalCompletionResults,
6746 completionBytes);
6747
6748 // How much memory is being used by SourceManager's content cache?
6749 createCXTUResourceUsageEntry(*entries,
6750 CXTUResourceUsage_SourceManagerContentCache,
6751 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6752
6753 // How much memory is being used by the MemoryBuffer's in SourceManager?
6754 const SourceManager::MemoryBufferSizes &srcBufs =
6755 astUnit->getSourceManager().getMemoryBufferSizes();
6756
6757 createCXTUResourceUsageEntry(*entries,
6758 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6759 (unsigned long) srcBufs.malloc_bytes);
6760 createCXTUResourceUsageEntry(*entries,
6761 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6762 (unsigned long) srcBufs.mmap_bytes);
6763 createCXTUResourceUsageEntry(*entries,
6764 CXTUResourceUsage_SourceManager_DataStructures,
6765 (unsigned long) astContext.getSourceManager()
6766 .getDataStructureSizes());
6767
6768 // How much memory is being used by the ExternalASTSource?
6769 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6770 const ExternalASTSource::MemoryBufferSizes &sizes =
6771 esrc->getMemoryBufferSizes();
6772
6773 createCXTUResourceUsageEntry(*entries,
6774 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6775 (unsigned long) sizes.malloc_bytes);
6776 createCXTUResourceUsageEntry(*entries,
6777 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6778 (unsigned long) sizes.mmap_bytes);
6779 }
6780
6781 // How much memory is being used by the Preprocessor?
6782 Preprocessor &pp = astUnit->getPreprocessor();
6783 createCXTUResourceUsageEntry(*entries,
6784 CXTUResourceUsage_Preprocessor,
6785 pp.getTotalMemory());
6786
6787 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6788 createCXTUResourceUsageEntry(*entries,
6789 CXTUResourceUsage_PreprocessingRecord,
6790 pRec->getTotalMemory());
6791 }
6792
6793 createCXTUResourceUsageEntry(*entries,
6794 CXTUResourceUsage_Preprocessor_HeaderSearch,
6795 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006796
Guy Benyei11169dd2012-12-18 14:30:41 +00006797 CXTUResourceUsage usage = { (void*) entries.get(),
6798 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006799 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006800 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006801 return usage;
6802}
6803
6804void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6805 if (usage.data)
6806 delete (MemUsageEntries*) usage.data;
6807}
6808
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006809CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6810 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006811 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006812 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006813
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006814 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006815 LOG_BAD_TU(TU);
6816 return skipped;
6817 }
6818
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006819 if (!file)
6820 return skipped;
6821
6822 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6823 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6824 if (!ppRec)
6825 return skipped;
6826
6827 ASTContext &Ctx = astUnit->getASTContext();
6828 SourceManager &sm = Ctx.getSourceManager();
6829 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6830 FileID wantedFileID = sm.translateFile(fileEntry);
6831
6832 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6833 std::vector<SourceRange> wantedRanges;
6834 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6835 i != ei; ++i) {
6836 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6837 wantedRanges.push_back(*i);
6838 }
6839
6840 skipped->count = wantedRanges.size();
6841 skipped->ranges = new CXSourceRange[skipped->count];
6842 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6843 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6844
6845 return skipped;
6846}
6847
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006848void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6849 if (ranges) {
6850 delete[] ranges->ranges;
6851 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006852 }
6853}
6854
Guy Benyei11169dd2012-12-18 14:30:41 +00006855} // end extern "C"
6856
6857void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6858 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6859 for (unsigned I = 0; I != Usage.numEntries; ++I)
6860 fprintf(stderr, " %s: %lu\n",
6861 clang_getTUResourceUsageName(Usage.entries[I].kind),
6862 Usage.entries[I].amount);
6863
6864 clang_disposeCXTUResourceUsage(Usage);
6865}
6866
6867//===----------------------------------------------------------------------===//
6868// Misc. utility functions.
6869//===----------------------------------------------------------------------===//
6870
6871/// Default to using an 8 MB stack size on "safety" threads.
6872static unsigned SafetyStackThreadSize = 8 << 20;
6873
6874namespace clang {
6875
6876bool RunSafely(llvm::CrashRecoveryContext &CRC,
6877 void (*Fn)(void*), void *UserData,
6878 unsigned Size) {
6879 if (!Size)
6880 Size = GetSafetyThreadStackSize();
6881 if (Size)
6882 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6883 return CRC.RunSafely(Fn, UserData);
6884}
6885
6886unsigned GetSafetyThreadStackSize() {
6887 return SafetyStackThreadSize;
6888}
6889
6890void SetSafetyThreadStackSize(unsigned Value) {
6891 SafetyStackThreadSize = Value;
6892}
6893
6894}
6895
6896void clang::setThreadBackgroundPriority() {
6897 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6898 return;
6899
Alp Toker1a86ad22014-07-06 06:24:00 +00006900#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006901 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6902#endif
6903}
6904
6905void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6906 if (!Unit)
6907 return;
6908
6909 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6910 DEnd = Unit->stored_diag_end();
6911 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006912 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006913 CXString Msg = clang_formatDiagnostic(&Diag,
6914 clang_defaultDiagnosticDisplayOptions());
6915 fprintf(stderr, "%s\n", clang_getCString(Msg));
6916 clang_disposeString(Msg);
6917 }
6918#ifdef LLVM_ON_WIN32
6919 // On Windows, force a flush, since there may be multiple copies of
6920 // stderr and stdout in the file system, all with different buffers
6921 // but writing to the same device.
6922 fflush(stderr);
6923#endif
6924}
6925
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006926MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6927 SourceLocation MacroDefLoc,
6928 CXTranslationUnit TU){
6929 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006930 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006931 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006932 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006933
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006934 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006935 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006936 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006937 if (MD) {
6938 for (MacroDirective::DefInfo
6939 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6940 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6941 return Def.getMacroInfo();
6942 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006943 }
6944
Craig Topper69186e72014-06-08 08:38:04 +00006945 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006946}
6947
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006948const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6949 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006950 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006951 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006952 const IdentifierInfo *II = MacroDef->getName();
6953 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006954 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006955
6956 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6957}
6958
6959MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6960 const Token &Tok,
6961 CXTranslationUnit TU) {
6962 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006963 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006964 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006965 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006966
6967 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006968 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006969 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6970 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006971 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006972
6973 // Check that the token is inside the definition and not its argument list.
6974 SourceManager &SM = Unit->getSourceManager();
6975 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006976 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006977 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006978 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006979
6980 Preprocessor &PP = Unit->getPreprocessor();
6981 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6982 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006983 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006984
Alp Toker2d57cea2014-05-17 04:53:25 +00006985 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006986 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006987 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006988
6989 // Check that the identifier is not one of the macro arguments.
6990 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006991 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006992
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006993 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6994 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006995 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006996
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006997 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006998}
6999
7000MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7001 SourceLocation Loc,
7002 CXTranslationUnit TU) {
7003 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007004 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007005
7006 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007007 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007008 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007009 Preprocessor &PP = Unit->getPreprocessor();
7010 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007011 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007012 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7013 Token Tok;
7014 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007015 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007016
7017 return checkForMacroInMacroDefinition(MI, Tok, TU);
7018}
7019
Guy Benyei11169dd2012-12-18 14:30:41 +00007020extern "C" {
7021
7022CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007023 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007024}
7025
7026} // end: extern "C"
7027
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007028Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7029 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007030 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007031 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007032 if (Unit->isMainFileAST())
7033 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007034 return *this;
7035 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007036 } else {
7037 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007038 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007039 return *this;
7040}
7041
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007042Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7043 *this << FE->getName();
7044 return *this;
7045}
7046
7047Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7048 CXString cursorName = clang_getCursorDisplayName(cursor);
7049 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7050 clang_disposeString(cursorName);
7051 return *this;
7052}
7053
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007054Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7055 CXFile File;
7056 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007057 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007058 CXString FileName = clang_getFileName(File);
7059 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7060 clang_disposeString(FileName);
7061 return *this;
7062}
7063
7064Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7065 CXSourceLocation BLoc = clang_getRangeStart(range);
7066 CXSourceLocation ELoc = clang_getRangeEnd(range);
7067
7068 CXFile BFile;
7069 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007070 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007071
7072 CXFile EFile;
7073 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007074 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007075
7076 CXString BFileName = clang_getFileName(BFile);
7077 if (BFile == EFile) {
7078 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7079 BLine, BColumn, ELine, EColumn);
7080 } else {
7081 CXString EFileName = clang_getFileName(EFile);
7082 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7083 BLine, BColumn)
7084 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7085 ELine, EColumn);
7086 clang_disposeString(EFileName);
7087 }
7088 clang_disposeString(BFileName);
7089 return *this;
7090}
7091
7092Logger &cxindex::Logger::operator<<(CXString Str) {
7093 *this << clang_getCString(Str);
7094 return *this;
7095}
7096
7097Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7098 LogOS << Fmt;
7099 return *this;
7100}
7101
Chandler Carruth37ad2582014-06-27 15:14:39 +00007102static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7103
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007104cxindex::Logger::~Logger() {
7105 LogOS.flush();
7106
Chandler Carruth37ad2582014-06-27 15:14:39 +00007107 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007108
7109 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7110
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007111 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007112 OS << "[libclang:" << Name << ':';
7113
Alp Toker1a86ad22014-07-06 06:24:00 +00007114#ifdef USE_DARWIN_THREADS
7115 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007116 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7117 OS << tid << ':';
7118#endif
7119
7120 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7121 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7122 OS << Msg.str() << '\n';
7123
7124 if (Trace) {
7125 llvm::sys::PrintStackTrace(stderr);
7126 OS << "--------------------------------------------------\n";
7127 }
7128}