blob: eb1765efbc2f7335c78ab1e8ee8596ddf4cdce2e [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873
Guy Benyei11169dd2012-12-18 14:30:41 +00001874private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001876 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1877 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1879 void AddStmt(const Stmt *S);
1880 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001883 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884};
1885} // end anonyous namespace
1886
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 // 'S' should always be non-null, since it comes from the
1889 // statement we are visiting.
1890 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1891}
1892
1893void
1894EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1895 if (Qualifier)
1896 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1897}
1898
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001899void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001900 if (S)
1901 WL.push_back(StmtVisit(S, Parent));
1902}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 if (D)
1905 WL.push_back(DeclVisit(D, Parent, isFirst));
1906}
1907void EnqueueVisitor::
1908 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1909 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001911}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 if (D)
1914 WL.push_back(MemberRefVisit(D, L, Parent));
1915}
1916void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1917 if (TI)
1918 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1919 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001921 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001922 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001923 AddStmt(*Child);
1924 }
1925 if (size == WL.size())
1926 return;
1927 // Now reverse the entries we just added. This will match the DFS
1928 // ordering performed by the worklist.
1929 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1930 std::reverse(I, E);
1931}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932namespace {
1933class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1934 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001935 /// \brief Process clauses with list of variables.
1936 template <typename T>
1937 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938public:
1939 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1940#define OPENMP_CLAUSE(Name, Class) \
1941 void Visit##Class(const Class *C);
1942#include "clang/Basic/OpenMPKinds.def"
1943};
1944
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001945void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1946 Visitor->AddStmt(C->getCondition());
1947}
1948
Alexey Bataev3778b602014-07-17 07:32:53 +00001949void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1950 Visitor->AddStmt(C->getCondition());
1951}
1952
Alexey Bataev568a8332014-03-06 06:15:19 +00001953void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1954 Visitor->AddStmt(C->getNumThreads());
1955}
1956
Alexey Bataev62c87d22014-03-21 04:51:18 +00001957void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1958 Visitor->AddStmt(C->getSafelen());
1959}
1960
Alexander Musman8bd31e62014-05-27 15:12:19 +00001961void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1962 Visitor->AddStmt(C->getNumForLoops());
1963}
1964
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001966
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001967void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1968
Alexey Bataev56dafe82014-06-20 07:16:17 +00001969void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1970 Visitor->AddStmt(C->getChunkSize());
1971}
1972
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001973void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1974
Alexey Bataev236070f2014-06-20 11:19:47 +00001975void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1976
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001977void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1978
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001979void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1980
Alexey Bataev756c1962013-09-24 03:17:45 +00001981template<typename T>
1982void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001983 for (const auto *I : Node->varlists())
1984 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001985}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001986
1987void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001988 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001989}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001990void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1991 const OMPFirstprivateClause *C) {
1992 VisitOMPClauseList(C);
1993}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001994void OMPClauseEnqueue::VisitOMPLastprivateClause(
1995 const OMPLastprivateClause *C) {
1996 VisitOMPClauseList(C);
1997}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001998void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001999 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002000}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002001void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2002 VisitOMPClauseList(C);
2003}
Alexander Musman8dba6642014-04-22 13:09:42 +00002004void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2005 VisitOMPClauseList(C);
2006 Visitor->AddStmt(C->getStep());
2007}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002008void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2009 VisitOMPClauseList(C);
2010 Visitor->AddStmt(C->getAlignment());
2011}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002012void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002015void
2016OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2017 VisitOMPClauseList(C);
2018}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019}
Alexey Bataev756c1962013-09-24 03:17:45 +00002020
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002021void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2022 unsigned size = WL.size();
2023 OMPClauseEnqueue Visitor(this);
2024 Visitor.Visit(S);
2025 if (size == WL.size())
2026 return;
2027 // Now reverse the entries we just added. This will match the DFS
2028 // ordering performed by the worklist.
2029 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2030 std::reverse(I, E);
2031}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 AddDecl(B->getBlockDecl());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 EnqueueChildren(E);
2040 AddTypeLoc(E->getTypeSourceInfo());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2043 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 E = S->body_rend(); I != E; ++I) {
2045 AddStmt(*I);
2046 }
2047}
2048void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 AddStmt(S->getSubStmt());
2051 AddDeclarationNameInfo(S);
2052 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2053 AddNestedNameSpecifierLoc(QualifierLoc);
2054}
2055
2056void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2059 AddDeclarationNameInfo(E);
2060 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2061 AddNestedNameSpecifierLoc(QualifierLoc);
2062 if (!E->isImplicitAccess())
2063 AddStmt(E->getBase());
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 // Enqueue the initializer , if any.
2067 AddStmt(E->getInitializer());
2068 // Enqueue the array size, if any.
2069 AddStmt(E->getArraySize());
2070 // Enqueue the allocated type.
2071 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2072 // Enqueue the placement arguments.
2073 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2074 AddStmt(E->getPlacementArg(I-1));
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2078 AddStmt(CE->getArg(I-1));
2079 AddStmt(CE->getCallee());
2080 AddStmt(CE->getArg(0));
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2083 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 // Visit the name of the type being destroyed.
2085 AddTypeLoc(E->getDestroyedTypeInfo());
2086 // Visit the scope type that looks disturbingly like the nested-name-specifier
2087 // but isn't.
2088 AddTypeLoc(E->getScopeTypeInfo());
2089 // Visit the nested-name-specifier.
2090 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2091 AddNestedNameSpecifierLoc(QualifierLoc);
2092 // Visit base expression.
2093 AddStmt(E->getBase());
2094}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2096 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 AddTypeLoc(E->getTypeSourceInfo());
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2100 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 EnqueueChildren(E);
2102 AddTypeLoc(E->getTypeSourceInfo());
2103}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 EnqueueChildren(E);
2106 if (E->isTypeOperand())
2107 AddTypeLoc(E->getTypeOperandSourceInfo());
2108}
2109
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2111 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 EnqueueChildren(E);
2113 AddTypeLoc(E->getTypeSourceInfo());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 EnqueueChildren(E);
2117 if (E->isTypeOperand())
2118 AddTypeLoc(E->getTypeOperandSourceInfo());
2119}
2120
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 EnqueueChildren(S);
2123 AddDecl(S->getExceptionDecl());
2124}
2125
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 if (DR->hasExplicitTemplateArgs()) {
2128 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2129 }
2130 WL.push_back(DeclRefExprParts(DR, Parent));
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2133 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2135 AddDeclarationNameInfo(E);
2136 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 unsigned size = WL.size();
2140 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002141 for (const auto *D : S->decls()) {
2142 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 isFirst = false;
2144 }
2145 if (size == WL.size())
2146 return;
2147 // Now reverse the entries we just added. This will match the DFS
2148 // ordering performed by the worklist.
2149 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2150 std::reverse(I, E);
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 D = E->designators_rbegin(), DEnd = E->designators_rend();
2156 D != DEnd; ++D) {
2157 if (D->isFieldDesignator()) {
2158 if (FieldDecl *Field = D->getField())
2159 AddMemberRef(Field, D->getFieldLoc());
2160 continue;
2161 }
2162 if (D->isArrayDesignator()) {
2163 AddStmt(E->getArrayIndex(*D));
2164 continue;
2165 }
2166 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2167 AddStmt(E->getArrayRangeEnd(*D));
2168 AddStmt(E->getArrayRangeStart(*D));
2169 }
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(E);
2173 AddTypeLoc(E->getTypeInfoAsWritten());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddStmt(FS->getBody());
2177 AddStmt(FS->getInc());
2178 AddStmt(FS->getCond());
2179 AddDecl(FS->getConditionVariable());
2180 AddStmt(FS->getInit());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 AddStmt(If->getElse());
2187 AddStmt(If->getThen());
2188 AddStmt(If->getCond());
2189 AddDecl(If->getConditionVariable());
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 // We care about the syntactic form of the initializer list, only.
2193 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2194 IE = Syntactic;
2195 EnqueueChildren(IE);
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 WL.push_back(MemberExprParts(M, Parent));
2199
2200 // If the base of the member access expression is an implicit 'this', don't
2201 // visit it.
2202 // FIXME: If we ever want to show these implicit accesses, this will be
2203 // unfortunate. However, clang_getCursor() relies on this behavior.
2204 if (!M->isImplicitAccess())
2205 AddStmt(M->getBase());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddTypeLoc(E->getEncodedTypeSourceInfo());
2209}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 EnqueueChildren(M);
2212 AddTypeLoc(M->getClassReceiverTypeInfo());
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 // Visit the components of the offsetof expression.
2216 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2217 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2218 const OffsetOfNode &Node = E->getComponent(I-1);
2219 switch (Node.getKind()) {
2220 case OffsetOfNode::Array:
2221 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2222 break;
2223 case OffsetOfNode::Field:
2224 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2225 break;
2226 case OffsetOfNode::Identifier:
2227 case OffsetOfNode::Base:
2228 continue;
2229 }
2230 }
2231 // Visit the type into which we're computing the offset.
2232 AddTypeLoc(E->getTypeSourceInfo());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2236 WL.push_back(OverloadExprParts(E, Parent));
2237}
2238void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueChildren(E);
2241 if (E->isArgumentType())
2242 AddTypeLoc(E->getArgumentTypeInfo());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 EnqueueChildren(S);
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 AddStmt(S->getBody());
2249 AddStmt(S->getCond());
2250 AddDecl(S->getConditionVariable());
2251}
2252
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 AddStmt(W->getBody());
2255 AddStmt(W->getCond());
2256 AddDecl(W->getConditionVariable());
2257}
2258
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 for (unsigned I = E->getNumArgs(); I > 0; --I)
2261 AddTypeLoc(E->getArg(I-1));
2262}
2263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 AddTypeLoc(E->getQueriedTypeSourceInfo());
2266}
2267
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 EnqueueChildren(E);
2270}
2271
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 VisitOverloadExpr(U);
2274 if (!U->isImplicitAccess())
2275 AddStmt(U->getBase());
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 AddStmt(E->getSubExpr());
2279 AddTypeLoc(E->getWrittenTypeInfo());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 WL.push_back(SizeOfPackExprParts(E, Parent));
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 // If the opaque value has a source expression, just transparently
2286 // visit that. This is useful for (e.g.) pseudo-object expressions.
2287 if (Expr *SourceExpr = E->getSourceExpr())
2288 return Visit(SourceExpr);
2289}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddStmt(E->getBody());
2292 WL.push_back(LambdaExprParts(E, Parent));
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 // Treat the expression like its syntactic form.
2296 Visit(E->getSyntacticForm());
2297}
2298
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002299void EnqueueVisitor::VisitOMPExecutableDirective(
2300 const OMPExecutableDirective *D) {
2301 EnqueueChildren(D);
2302 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2303 E = D->clauses().end();
2304 I != E; ++I)
2305 EnqueueChildren(*I);
2306}
2307
2308void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2309 VisitOMPExecutableDirective(D);
2310}
2311
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002312void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2313 VisitOMPExecutableDirective(D);
2314}
2315
Alexey Bataevf29276e2014-06-18 04:14:57 +00002316void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002320void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2321 VisitOMPExecutableDirective(D);
2322}
2323
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002324void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002328void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexander Musman80c22892014-07-17 08:54:58 +00002332void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002336void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338 AddDeclarationNameInfo(D);
2339}
2340
Alexey Bataev4acb8592014-07-07 13:01:15 +00002341void
2342EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2343 VisitOMPExecutableDirective(D);
2344}
2345
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002346void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2347 const OMPParallelSectionsDirective *D) {
2348 VisitOMPExecutableDirective(D);
2349}
2350
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002351void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2352 VisitOMPExecutableDirective(D);
2353}
2354
Alexey Bataev68446b72014-07-18 07:47:19 +00002355void
2356EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358}
2359
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002360void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2361 VisitOMPExecutableDirective(D);
2362}
2363
Alexey Bataev2df347a2014-07-18 10:17:07 +00002364void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2365 VisitOMPExecutableDirective(D);
2366}
2367
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2370}
2371
2372bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2373 if (RegionOfInterest.isValid()) {
2374 SourceRange Range = getRawCursorExtent(C);
2375 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2376 return false;
2377 }
2378 return true;
2379}
2380
2381bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2382 while (!WL.empty()) {
2383 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002384 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002385
2386 // Set the Parent field, then back to its old value once we're done.
2387 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2388
2389 switch (LI.getKind()) {
2390 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 if (!D)
2393 continue;
2394
2395 // For now, perform default visitation for Decls.
2396 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2397 cast<DeclVisit>(&LI)->isFirst())))
2398 return true;
2399
2400 continue;
2401 }
2402 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2403 const ASTTemplateArgumentListInfo *ArgList =
2404 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2405 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2406 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2407 Arg != ArgEnd; ++Arg) {
2408 if (VisitTemplateArgumentLoc(*Arg))
2409 return true;
2410 }
2411 continue;
2412 }
2413 case VisitorJob::TypeLocVisitKind: {
2414 // Perform default visitation for TypeLocs.
2415 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2416 return true;
2417 continue;
2418 }
2419 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 if (LabelStmt *stmt = LS->getStmt()) {
2422 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2423 TU))) {
2424 return true;
2425 }
2426 }
2427 continue;
2428 }
2429
2430 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2431 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2432 if (VisitNestedNameSpecifierLoc(V->get()))
2433 return true;
2434 continue;
2435 }
2436
2437 case VisitorJob::DeclarationNameInfoVisitKind: {
2438 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2439 ->get()))
2440 return true;
2441 continue;
2442 }
2443 case VisitorJob::MemberRefVisitKind: {
2444 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2445 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2446 return true;
2447 continue;
2448 }
2449 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 if (!S)
2452 continue;
2453
2454 // Update the current cursor.
2455 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2456 if (!IsInRegionOfInterest(Cursor))
2457 continue;
2458 switch (Visitor(Cursor, Parent, ClientData)) {
2459 case CXChildVisit_Break: return true;
2460 case CXChildVisit_Continue: break;
2461 case CXChildVisit_Recurse:
2462 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002463 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 EnqueueWorkList(WL, S);
2465 break;
2466 }
2467 continue;
2468 }
2469 case VisitorJob::MemberExprPartsKind: {
2470 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002472
2473 // Visit the nested-name-specifier
2474 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2475 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2476 return true;
2477
2478 // Visit the declaration name.
2479 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2480 return true;
2481
2482 // Visit the explicitly-specified template arguments, if any.
2483 if (M->hasExplicitTemplateArgs()) {
2484 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2485 *ArgEnd = Arg + M->getNumTemplateArgs();
2486 Arg != ArgEnd; ++Arg) {
2487 if (VisitTemplateArgumentLoc(*Arg))
2488 return true;
2489 }
2490 }
2491 continue;
2492 }
2493 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002494 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002495 // Visit nested-name-specifier, if present.
2496 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2497 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2498 return true;
2499 // Visit declaration name.
2500 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2501 return true;
2502 continue;
2503 }
2504 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 // Visit the nested-name-specifier.
2507 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2508 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2509 return true;
2510 // Visit the declaration name.
2511 if (VisitDeclarationNameInfo(O->getNameInfo()))
2512 return true;
2513 // Visit the overloaded declaration reference.
2514 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2515 return true;
2516 continue;
2517 }
2518 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 NamedDecl *Pack = E->getPack();
2521 if (isa<TemplateTypeParmDecl>(Pack)) {
2522 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2523 E->getPackLoc(), TU)))
2524 return true;
2525
2526 continue;
2527 }
2528
2529 if (isa<TemplateTemplateParmDecl>(Pack)) {
2530 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2531 E->getPackLoc(), TU)))
2532 return true;
2533
2534 continue;
2535 }
2536
2537 // Non-type template parameter packs and function parameter packs are
2538 // treated like DeclRefExpr cursors.
2539 continue;
2540 }
2541
2542 case VisitorJob::LambdaExprPartsKind: {
2543 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002544 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2546 CEnd = E->explicit_capture_end();
2547 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002548 // FIXME: Lambda init-captures.
2549 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002551
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2553 C->getLocation(),
2554 TU)))
2555 return true;
2556 }
2557
2558 // Visit parameters and return type, if present.
2559 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2560 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2561 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2562 // Visit the whole type.
2563 if (Visit(TL))
2564 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002565 } else if (FunctionProtoTypeLoc Proto =
2566 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 if (E->hasExplicitParameters()) {
2568 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002569 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2570 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002571 return true;
2572 } else {
2573 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002574 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 return true;
2576 }
2577 }
2578 }
2579 break;
2580 }
2581
2582 case VisitorJob::PostChildrenVisitKind:
2583 if (PostChildrenVisitor(Parent, ClientData))
2584 return true;
2585 break;
2586 }
2587 }
2588 return false;
2589}
2590
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002591bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002592 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002593 if (!WorkListFreeList.empty()) {
2594 WL = WorkListFreeList.back();
2595 WL->clear();
2596 WorkListFreeList.pop_back();
2597 }
2598 else {
2599 WL = new VisitorWorkList();
2600 WorkListCache.push_back(WL);
2601 }
2602 EnqueueWorkList(*WL, S);
2603 bool result = RunVisitorWorkList(*WL);
2604 WorkListFreeList.push_back(WL);
2605 return result;
2606}
2607
2608namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002609typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002610RefNamePieces
2611buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2612 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2613 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002614 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2615 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2616 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2617
2618 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2619
2620 RefNamePieces Pieces;
2621
2622 if (WantQualifier && QLoc.isValid())
2623 Pieces.push_back(QLoc);
2624
2625 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2626 Pieces.push_back(NI.getLoc());
2627
2628 if (WantTemplateArgs && TemplateArgs)
2629 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2630 TemplateArgs->RAngleLoc));
2631
2632 if (Kind == DeclarationName::CXXOperatorName) {
2633 Pieces.push_back(SourceLocation::getFromRawEncoding(
2634 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2635 Pieces.push_back(SourceLocation::getFromRawEncoding(
2636 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2637 }
2638
2639 if (WantSinglePiece) {
2640 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2641 Pieces.clear();
2642 Pieces.push_back(R);
2643 }
2644
2645 return Pieces;
2646}
2647}
2648
2649//===----------------------------------------------------------------------===//
2650// Misc. API hooks.
2651//===----------------------------------------------------------------------===//
2652
Chad Rosier05c71aa2013-03-27 18:28:23 +00002653static void fatal_error_handler(void *user_data, const std::string& reason,
2654 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002655 // Write the result out to stderr avoiding errs() because raw_ostreams can
2656 // call report_fatal_error.
2657 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2658 ::abort();
2659}
2660
Chandler Carruth66660742014-06-27 16:37:27 +00002661namespace {
2662struct RegisterFatalErrorHandler {
2663 RegisterFatalErrorHandler() {
2664 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2665 }
2666};
2667}
2668
2669static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2670
Guy Benyei11169dd2012-12-18 14:30:41 +00002671extern "C" {
2672CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2673 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002674 // We use crash recovery to make some of our APIs more reliable, implicitly
2675 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002676 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2677 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002678
Chandler Carruth66660742014-06-27 16:37:27 +00002679 // Look through the managed static to trigger construction of the managed
2680 // static which registers our fatal error handler. This ensures it is only
2681 // registered once.
2682 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002683
2684 CIndexer *CIdxr = new CIndexer();
2685 if (excludeDeclarationsFromPCH)
2686 CIdxr->setOnlyLocalDecls();
2687 if (displayDiagnostics)
2688 CIdxr->setDisplayDiagnostics();
2689
2690 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2691 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2692 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2693 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2694 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2695 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2696
2697 return CIdxr;
2698}
2699
2700void clang_disposeIndex(CXIndex CIdx) {
2701 if (CIdx)
2702 delete static_cast<CIndexer *>(CIdx);
2703}
2704
2705void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2706 if (CIdx)
2707 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2708}
2709
2710unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2711 if (CIdx)
2712 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2713 return 0;
2714}
2715
2716void clang_toggleCrashRecovery(unsigned isEnabled) {
2717 if (isEnabled)
2718 llvm::CrashRecoveryContext::Enable();
2719 else
2720 llvm::CrashRecoveryContext::Disable();
2721}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002722
Guy Benyei11169dd2012-12-18 14:30:41 +00002723CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2724 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002725 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002726 enum CXErrorCode Result =
2727 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002728 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002729 assert((TU && Result == CXError_Success) ||
2730 (!TU && Result != CXError_Success));
2731 return TU;
2732}
2733
2734enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2735 const char *ast_filename,
2736 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002737 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002738 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002739
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002740 if (!CIdx || !ast_filename || !out_TU)
2741 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002742
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002743 LOG_FUNC_SECTION {
2744 *Log << ast_filename;
2745 }
2746
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2748 FileSystemOptions FileSystemOpts;
2749
2750 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002751 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002752 CXXIdx->getOnlyLocalDecls(), None,
2753 /*CaptureDiagnostics=*/true,
2754 /*AllowPCHWithCompilerErrors=*/true,
2755 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002756 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2757 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002758}
2759
2760unsigned clang_defaultEditingTranslationUnitOptions() {
2761 return CXTranslationUnit_PrecompiledPreamble |
2762 CXTranslationUnit_CacheCompletionResults;
2763}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002764
Guy Benyei11169dd2012-12-18 14:30:41 +00002765CXTranslationUnit
2766clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2767 const char *source_filename,
2768 int num_command_line_args,
2769 const char * const *command_line_args,
2770 unsigned num_unsaved_files,
2771 struct CXUnsavedFile *unsaved_files) {
2772 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2773 return clang_parseTranslationUnit(CIdx, source_filename,
2774 command_line_args, num_command_line_args,
2775 unsaved_files, num_unsaved_files,
2776 Options);
2777}
2778
2779struct ParseTranslationUnitInfo {
2780 CXIndex CIdx;
2781 const char *source_filename;
2782 const char *const *command_line_args;
2783 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002784 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002785 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002786 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002787 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002788};
2789static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002790 const ParseTranslationUnitInfo *PTUI =
2791 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 CXIndex CIdx = PTUI->CIdx;
2793 const char *source_filename = PTUI->source_filename;
2794 const char * const *command_line_args = PTUI->command_line_args;
2795 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002797 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002798
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002799 // Set up the initial return values.
2800 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002801 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002802
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002803 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002804 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002807 }
2808
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2810
2811 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2812 setThreadBackgroundPriority();
2813
2814 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2815 // FIXME: Add a flag for modules.
2816 TranslationUnitKind TUKind
2817 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002818 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002819 = options & CXTranslationUnit_CacheCompletionResults;
2820 bool IncludeBriefCommentsInCodeCompletion
2821 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2822 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2823 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2824
2825 // Configure the diagnostics.
2826 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002827 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002828
2829 // Recover resources if we crash before exiting this function.
2830 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2831 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002832 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002833
Ahmed Charlesb8984322014-03-07 20:03:18 +00002834 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2835 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002836
2837 // Recover resources if we crash before exiting this function.
2838 llvm::CrashRecoveryContextCleanupRegistrar<
2839 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2840
Alp Toker9d85b182014-07-07 01:23:14 +00002841 for (auto &UF : PTUI->unsaved_files) {
2842 llvm::MemoryBuffer *MB =
2843 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2844 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 }
2846
Ahmed Charlesb8984322014-03-07 20:03:18 +00002847 std::unique_ptr<std::vector<const char *>> Args(
2848 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002849
2850 // Recover resources if we crash before exiting this method.
2851 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2852 ArgsCleanup(Args.get());
2853
2854 // Since the Clang C library is primarily used by batch tools dealing with
2855 // (often very broken) source code, where spell-checking can have a
2856 // significant negative impact on performance (particularly when
2857 // precompiled headers are involved), we disable it by default.
2858 // Only do this if we haven't found a spell-checking-related argument.
2859 bool FoundSpellCheckingArgument = false;
2860 for (int I = 0; I != num_command_line_args; ++I) {
2861 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2862 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2863 FoundSpellCheckingArgument = true;
2864 break;
2865 }
2866 }
2867 if (!FoundSpellCheckingArgument)
2868 Args->push_back("-fno-spell-checking");
2869
2870 Args->insert(Args->end(), command_line_args,
2871 command_line_args + num_command_line_args);
2872
2873 // The 'source_filename' argument is optional. If the caller does not
2874 // specify it then it is assumed that the source file is specified
2875 // in the actual argument list.
2876 // Put the source file after command_line_args otherwise if '-x' flag is
2877 // present it will be unused.
2878 if (source_filename)
2879 Args->push_back(source_filename);
2880
2881 // Do we need the detailed preprocessing record?
2882 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2883 Args->push_back("-Xclang");
2884 Args->push_back("-detailed-preprocessing-record");
2885 }
2886
2887 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002888 std::unique_ptr<ASTUnit> ErrUnit;
2889 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002890 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002891 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2892 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2893 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2894 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2895 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2896 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002897
2898 if (NumErrors != Diags->getClient()->getNumErrors()) {
2899 // Make sure to check that 'Unit' is non-NULL.
2900 if (CXXIdx->getDisplayDiagnostics())
2901 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2902 }
2903
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002904 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2905 PTUI->result = CXError_ASTReadError;
2906 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002907 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002908 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2909 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002910}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002911
2912CXTranslationUnit
2913clang_parseTranslationUnit(CXIndex CIdx,
2914 const char *source_filename,
2915 const char *const *command_line_args,
2916 int num_command_line_args,
2917 struct CXUnsavedFile *unsaved_files,
2918 unsigned num_unsaved_files,
2919 unsigned options) {
2920 CXTranslationUnit TU;
2921 enum CXErrorCode Result = clang_parseTranslationUnit2(
2922 CIdx, source_filename, command_line_args, num_command_line_args,
2923 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002924 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002925 assert((TU && Result == CXError_Success) ||
2926 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002927 return TU;
2928}
2929
2930enum CXErrorCode clang_parseTranslationUnit2(
2931 CXIndex CIdx,
2932 const char *source_filename,
2933 const char *const *command_line_args,
2934 int num_command_line_args,
2935 struct CXUnsavedFile *unsaved_files,
2936 unsigned num_unsaved_files,
2937 unsigned options,
2938 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002939 LOG_FUNC_SECTION {
2940 *Log << source_filename << ": ";
2941 for (int i = 0; i != num_command_line_args; ++i)
2942 *Log << command_line_args[i] << " ";
2943 }
2944
Alp Toker9d85b182014-07-07 01:23:14 +00002945 if (num_unsaved_files && !unsaved_files)
2946 return CXError_InvalidArguments;
2947
Alp Toker5c532982014-07-07 22:42:03 +00002948 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002949 ParseTranslationUnitInfo PTUI = {
2950 CIdx,
2951 source_filename,
2952 command_line_args,
2953 num_command_line_args,
2954 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2955 options,
2956 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002957 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002958 llvm::CrashRecoveryContext CRC;
2959
2960 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2961 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2962 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2963 fprintf(stderr, " 'command_line_args' : [");
2964 for (int i = 0; i != num_command_line_args; ++i) {
2965 if (i)
2966 fprintf(stderr, ", ");
2967 fprintf(stderr, "'%s'", command_line_args[i]);
2968 }
2969 fprintf(stderr, "],\n");
2970 fprintf(stderr, " 'unsaved_files' : [");
2971 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2972 if (i)
2973 fprintf(stderr, ", ");
2974 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2975 unsaved_files[i].Length);
2976 }
2977 fprintf(stderr, "],\n");
2978 fprintf(stderr, " 'options' : %d,\n", options);
2979 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980
2981 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983 if (CXTranslationUnit *TU = PTUI.out_TU)
2984 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 }
Alp Toker5c532982014-07-07 22:42:03 +00002986
2987 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002988}
2989
2990unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2991 return CXSaveTranslationUnit_None;
2992}
2993
2994namespace {
2995
2996struct SaveTranslationUnitInfo {
2997 CXTranslationUnit TU;
2998 const char *FileName;
2999 unsigned options;
3000 CXSaveError result;
3001};
3002
3003}
3004
3005static void clang_saveTranslationUnit_Impl(void *UserData) {
3006 SaveTranslationUnitInfo *STUI =
3007 static_cast<SaveTranslationUnitInfo*>(UserData);
3008
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003009 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3011 setThreadBackgroundPriority();
3012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003013 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3015}
3016
3017int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3018 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003019 LOG_FUNC_SECTION {
3020 *Log << TU << ' ' << FileName;
3021 }
3022
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003023 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003024 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003025 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003026 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3030 if (!CXXUnit->hasSema())
3031 return CXSaveError_InvalidTU;
3032
3033 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3034
3035 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3036 getenv("LIBCLANG_NOTHREADS")) {
3037 clang_saveTranslationUnit_Impl(&STUI);
3038
3039 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3040 PrintLibclangResourceUsage(TU);
3041
3042 return STUI.result;
3043 }
3044
3045 // We have an AST that has invalid nodes due to compiler errors.
3046 // Use a crash recovery thread for protection.
3047
3048 llvm::CrashRecoveryContext CRC;
3049
3050 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3051 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3052 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3053 fprintf(stderr, " 'options' : %d,\n", options);
3054 fprintf(stderr, "}\n");
3055
3056 return CXSaveError_Unknown;
3057
3058 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3059 PrintLibclangResourceUsage(TU);
3060 }
3061
3062 return STUI.result;
3063}
3064
3065void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3066 if (CTUnit) {
3067 // If the translation unit has been marked as unsafe to free, just discard
3068 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3070 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003071 return;
3072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003073 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003074 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3076 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003077 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 delete CTUnit;
3079 }
3080}
3081
3082unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3083 return CXReparse_None;
3084}
3085
3086struct ReparseTranslationUnitInfo {
3087 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003088 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003090 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003091};
3092
3093static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003094 const ReparseTranslationUnitInfo *RTUI =
3095 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003097 unsigned options = RTUI->options;
3098 (void) options;
3099
3100 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003101 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003102 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003103 RTUI->result = CXError_InvalidArguments;
3104 return;
3105 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
3107 // Reset the associated diagnostics.
3108 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003109 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003111 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3113 setThreadBackgroundPriority();
3114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003115 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003117
3118 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3119 new std::vector<ASTUnit::RemappedFile>());
3120
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 // Recover resources if we crash before exiting this function.
3122 llvm::CrashRecoveryContextCleanupRegistrar<
3123 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003124
3125 for (auto &UF : RTUI->unsaved_files) {
3126 llvm::MemoryBuffer *MB =
3127 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3128 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003130
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003131 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003132 RTUI->result = CXError_Success;
3133 else if (isASTReadError(CXXUnit))
3134 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003135}
3136
3137int clang_reparseTranslationUnit(CXTranslationUnit TU,
3138 unsigned num_unsaved_files,
3139 struct CXUnsavedFile *unsaved_files,
3140 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003141 LOG_FUNC_SECTION {
3142 *Log << TU;
3143 }
3144
Alp Toker9d85b182014-07-07 01:23:14 +00003145 if (num_unsaved_files && !unsaved_files)
3146 return CXError_InvalidArguments;
3147
Alp Toker5c532982014-07-07 22:42:03 +00003148 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003149 ReparseTranslationUnitInfo RTUI = {
3150 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003151 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003152
3153 if (getenv("LIBCLANG_NOTHREADS")) {
3154 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003155 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 }
3157
3158 llvm::CrashRecoveryContext CRC;
3159
3160 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3161 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003162 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003163 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3165 PrintLibclangResourceUsage(TU);
3166
Alp Toker5c532982014-07-07 22:42:03 +00003167 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003168}
3169
3170
3171CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003172 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003173 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003174 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003175 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003176
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003177 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003178 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003179}
3180
3181CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003182 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003183 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003184 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003185 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003186
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003187 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3189}
3190
3191} // end: extern "C"
3192
3193//===----------------------------------------------------------------------===//
3194// CXFile Operations.
3195//===----------------------------------------------------------------------===//
3196
3197extern "C" {
3198CXString clang_getFileName(CXFile SFile) {
3199 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003200 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003201
3202 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003203 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003204}
3205
3206time_t clang_getFileTime(CXFile SFile) {
3207 if (!SFile)
3208 return 0;
3209
3210 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3211 return FEnt->getModificationTime();
3212}
3213
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003214CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003215 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003216 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003217 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003218 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003219
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003220 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003221
3222 FileManager &FMgr = CXXUnit->getFileManager();
3223 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3224}
3225
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003226unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3227 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003228 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003229 LOG_BAD_TU(TU);
3230 return 0;
3231 }
3232
3233 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return 0;
3235
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003236 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 FileEntry *FEnt = static_cast<FileEntry *>(file);
3238 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3239 .isFileMultipleIncludeGuarded(FEnt);
3240}
3241
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003242int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3243 if (!file || !outID)
3244 return 1;
3245
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003246 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003247 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3248 outID->data[0] = ID.getDevice();
3249 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003250 outID->data[2] = FEnt->getModificationTime();
3251 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003252}
3253
Guy Benyei11169dd2012-12-18 14:30:41 +00003254} // end: extern "C"
3255
3256//===----------------------------------------------------------------------===//
3257// CXCursor Operations.
3258//===----------------------------------------------------------------------===//
3259
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003260static const Decl *getDeclFromExpr(const Stmt *E) {
3261 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return getDeclFromExpr(CE->getSubExpr());
3263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003264 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003266 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 if (PRE->isExplicitProperty())
3272 return PRE->getExplicitProperty();
3273 // It could be messaging both getter and setter as in:
3274 // ++myobj.myprop;
3275 // in which case prefer to associate the setter since it is less obvious
3276 // from inspecting the source that the setter is going to get called.
3277 if (PRE->isMessagingSetter())
3278 return PRE->getImplicitPropertySetter();
3279 return PRE->getImplicitPropertyGetter();
3280 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (Expr *Src = OVE->getSourceExpr())
3285 return getDeclFromExpr(Src);
3286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 if (!CE->isElidable())
3291 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 return OME->getMethodDecl();
3294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3299 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3302 isa<ParmVarDecl>(SizeOfPack->getPack()))
3303 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003304
3305 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003306}
3307
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003308static SourceLocation getLocationFromExpr(const Expr *E) {
3309 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 return getLocationFromExpr(CE->getSubExpr());
3311
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003312 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003314 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003316 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003318 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003320 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003322 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 return PropRef->getLocation();
3324
3325 return E->getLocStart();
3326}
3327
3328extern "C" {
3329
3330unsigned clang_visitChildren(CXCursor parent,
3331 CXCursorVisitor visitor,
3332 CXClientData client_data) {
3333 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3334 /*VisitPreprocessorLast=*/false);
3335 return CursorVis.VisitChildren(parent);
3336}
3337
3338#ifndef __has_feature
3339#define __has_feature(x) 0
3340#endif
3341#if __has_feature(blocks)
3342typedef enum CXChildVisitResult
3343 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3344
3345static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3346 CXClientData client_data) {
3347 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3348 return block(cursor, parent);
3349}
3350#else
3351// If we are compiled with a compiler that doesn't have native blocks support,
3352// define and call the block manually, so the
3353typedef struct _CXChildVisitResult
3354{
3355 void *isa;
3356 int flags;
3357 int reserved;
3358 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3359 CXCursor);
3360} *CXCursorVisitorBlock;
3361
3362static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3363 CXClientData client_data) {
3364 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3365 return block->invoke(block, cursor, parent);
3366}
3367#endif
3368
3369
3370unsigned clang_visitChildrenWithBlock(CXCursor parent,
3371 CXCursorVisitorBlock block) {
3372 return clang_visitChildren(parent, visitWithBlock, block);
3373}
3374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003375static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const ObjCPropertyImplDecl *PropImpl =
3382 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003386 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003388 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003389
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003390 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 }
3392
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003394 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003395
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3398 // and returns different names. NamedDecl returns the class name and
3399 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003400 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401
3402 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003403 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003404
3405 SmallString<1024> S;
3406 llvm::raw_svector_ostream os(S);
3407 ND->printName(os);
3408
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003409 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003410}
3411
3412CXString clang_getCursorSpelling(CXCursor C) {
3413 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003414 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003415
3416 if (clang_isReference(C.kind)) {
3417 switch (C.kind) {
3418 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003419 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003423 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003424 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 }
3426 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003427 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003429 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 }
3431 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003432 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
3435 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003436 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 assert(Type && "Missing type decl");
3438
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 getAsString());
3441 }
3442 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003443 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 assert(Template && "Missing template decl");
3445
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003446 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 }
3448
3449 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003450 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 assert(NS && "Missing namespace decl");
3452
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455
3456 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003457 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 assert(Field && "Missing member decl");
3459
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003460 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 }
3462
3463 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003464 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 assert(Label && "Missing label");
3466
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003467 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 }
3469
3470 case CXCursor_OverloadedDeclRef: {
3471 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003472 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3473 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003474 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003475 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003478 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 OverloadedTemplateStorage *Ovl
3480 = Storage.get<OverloadedTemplateStorage*>();
3481 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003482 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003483 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 }
3485
3486 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003487 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 assert(Var && "Missing variable decl");
3489
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003490 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 }
3492
3493 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003494 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 }
3496 }
3497
3498 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003499 const Expr *E = getCursorExpr(C);
3500
3501 if (C.kind == CXCursor_ObjCStringLiteral ||
3502 C.kind == CXCursor_StringLiteral) {
3503 const StringLiteral *SLit;
3504 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3505 SLit = OSL->getString();
3506 } else {
3507 SLit = cast<StringLiteral>(E);
3508 }
3509 SmallString<256> Buf;
3510 llvm::raw_svector_ostream OS(Buf);
3511 SLit->outputString(OS);
3512 return cxstring::createDup(OS.str());
3513 }
3514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 if (D)
3517 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003518 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003522 const Stmt *S = getCursorStmt(C);
3523 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003524 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003526 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528
3529 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 ->getNameStart());
3532
3533 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 ->getNameStart());
3536
3537 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003538 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003539
3540 if (clang_isDeclaration(C.kind))
3541 return getDeclSpelling(getCursorDecl(C));
3542
3543 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003544 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003545 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 }
3547
3548 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003549 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003550 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003553 if (C.kind == CXCursor_PackedAttr) {
3554 return cxstring::createRef("packed");
3555 }
3556
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003557 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003558}
3559
3560CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3561 unsigned pieceIndex,
3562 unsigned options) {
3563 if (clang_Cursor_isNull(C))
3564 return clang_getNullRange();
3565
3566 ASTContext &Ctx = getCursorContext(C);
3567
3568 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003569 const Stmt *S = getCursorStmt(C);
3570 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 if (pieceIndex > 0)
3572 return clang_getNullRange();
3573 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3574 }
3575
3576 return clang_getNullRange();
3577 }
3578
3579 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003580 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3582 if (pieceIndex >= ME->getNumSelectorLocs())
3583 return clang_getNullRange();
3584 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3585 }
3586 }
3587
3588 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3589 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003590 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3592 if (pieceIndex >= MD->getNumSelectorLocs())
3593 return clang_getNullRange();
3594 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3595 }
3596 }
3597
3598 if (C.kind == CXCursor_ObjCCategoryDecl ||
3599 C.kind == CXCursor_ObjCCategoryImplDecl) {
3600 if (pieceIndex > 0)
3601 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003602 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3604 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003605 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3607 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3608 }
3609
3610 if (C.kind == CXCursor_ModuleImportDecl) {
3611 if (pieceIndex > 0)
3612 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const ImportDecl *ImportD =
3614 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3616 if (!Locs.empty())
3617 return cxloc::translateSourceRange(Ctx,
3618 SourceRange(Locs.front(), Locs.back()));
3619 }
3620 return clang_getNullRange();
3621 }
3622
3623 // FIXME: A CXCursor_InclusionDirective should give the location of the
3624 // filename, but we don't keep track of this.
3625
3626 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3627 // but we don't keep track of this.
3628
3629 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3630 // but we don't keep track of this.
3631
3632 // Default handling, give the location of the cursor.
3633
3634 if (pieceIndex > 0)
3635 return clang_getNullRange();
3636
3637 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3638 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3639 return cxloc::translateSourceRange(Ctx, Loc);
3640}
3641
3642CXString clang_getCursorDisplayName(CXCursor C) {
3643 if (!clang_isDeclaration(C.kind))
3644 return clang_getCursorSpelling(C);
3645
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003646 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003648 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003649
3650 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003651 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 D = FunTmpl->getTemplatedDecl();
3653
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003654 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 SmallString<64> Str;
3656 llvm::raw_svector_ostream OS(Str);
3657 OS << *Function;
3658 if (Function->getPrimaryTemplate())
3659 OS << "<>";
3660 OS << "(";
3661 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3662 if (I)
3663 OS << ", ";
3664 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3665 }
3666
3667 if (Function->isVariadic()) {
3668 if (Function->getNumParams())
3669 OS << ", ";
3670 OS << "...";
3671 }
3672 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003673 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003676 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 SmallString<64> Str;
3678 llvm::raw_svector_ostream OS(Str);
3679 OS << *ClassTemplate;
3680 OS << "<";
3681 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3682 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3683 if (I)
3684 OS << ", ";
3685
3686 NamedDecl *Param = Params->getParam(I);
3687 if (Param->getIdentifier()) {
3688 OS << Param->getIdentifier()->getName();
3689 continue;
3690 }
3691
3692 // There is no parameter name, which makes this tricky. Try to come up
3693 // with something useful that isn't too long.
3694 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3695 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3696 else if (NonTypeTemplateParmDecl *NTTP
3697 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3698 OS << NTTP->getType().getAsString(Policy);
3699 else
3700 OS << "template<...> class";
3701 }
3702
3703 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003704 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 }
3706
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003707 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3709 // If the type was explicitly written, use that.
3710 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003711 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003712
Benjamin Kramer9170e912013-02-22 15:46:01 +00003713 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 llvm::raw_svector_ostream OS(Str);
3715 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003716 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 ClassSpec->getTemplateArgs().data(),
3718 ClassSpec->getTemplateArgs().size(),
3719 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003720 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722
3723 return clang_getCursorSpelling(C);
3724}
3725
3726CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3727 switch (Kind) {
3728 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003856 case CXCursor_ObjCSelfExpr:
3857 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003946 case CXCursor_SEHLeaveStmt:
3947 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003976 case CXCursor_PackedAttr:
3977 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003978 case CXCursor_PureAttr:
3979 return cxstring::createRef("attribute(pure)");
3980 case CXCursor_ConstAttr:
3981 return cxstring::createRef("attribute(const)");
3982 case CXCursor_NoDuplicateAttr:
3983 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003984 case CXCursor_CUDAConstantAttr:
3985 return cxstring::createRef("attribute(constant)");
3986 case CXCursor_CUDADeviceAttr:
3987 return cxstring::createRef("attribute(device)");
3988 case CXCursor_CUDAGlobalAttr:
3989 return cxstring::createRef("attribute(global)");
3990 case CXCursor_CUDAHostAttr:
3991 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004040 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004041 return cxstring::createRef("OMPParallelDirective");
4042 case CXCursor_OMPSimdDirective:
4043 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004044 case CXCursor_OMPForDirective:
4045 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004046 case CXCursor_OMPSectionsDirective:
4047 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004048 case CXCursor_OMPSectionDirective:
4049 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004050 case CXCursor_OMPSingleDirective:
4051 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004052 case CXCursor_OMPMasterDirective:
4053 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004054 case CXCursor_OMPCriticalDirective:
4055 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004056 case CXCursor_OMPParallelForDirective:
4057 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004058 case CXCursor_OMPParallelSectionsDirective:
4059 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004060 case CXCursor_OMPTaskDirective:
4061 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004062 case CXCursor_OMPTaskyieldDirective:
4063 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004064 case CXCursor_OMPBarrierDirective:
4065 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004066 case CXCursor_OMPTaskwaitDirective:
4067 return cxstring::createRef("OMPTaskwaitDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 }
4069
4070 llvm_unreachable("Unhandled CXCursorKind");
4071}
4072
4073struct GetCursorData {
4074 SourceLocation TokenBeginLoc;
4075 bool PointsAtMacroArgExpansion;
4076 bool VisitedObjCPropertyImplDecl;
4077 SourceLocation VisitedDeclaratorDeclStartLoc;
4078 CXCursor &BestCursor;
4079
4080 GetCursorData(SourceManager &SM,
4081 SourceLocation tokenBegin, CXCursor &outputCursor)
4082 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4083 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4084 VisitedObjCPropertyImplDecl = false;
4085 }
4086};
4087
4088static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4089 CXCursor parent,
4090 CXClientData client_data) {
4091 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4092 CXCursor *BestCursor = &Data->BestCursor;
4093
4094 // If we point inside a macro argument we should provide info of what the
4095 // token is so use the actual cursor, don't replace it with a macro expansion
4096 // cursor.
4097 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4098 return CXChildVisit_Recurse;
4099
4100 if (clang_isDeclaration(cursor.kind)) {
4101 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004102 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4104 if (MD->isImplicit())
4105 return CXChildVisit_Break;
4106
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004107 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4109 // Check that when we have multiple @class references in the same line,
4110 // that later ones do not override the previous ones.
4111 // If we have:
4112 // @class Foo, Bar;
4113 // source ranges for both start at '@', so 'Bar' will end up overriding
4114 // 'Foo' even though the cursor location was at 'Foo'.
4115 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4116 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004117 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4119 if (PrevID != ID &&
4120 !PrevID->isThisDeclarationADefinition() &&
4121 !ID->isThisDeclarationADefinition())
4122 return CXChildVisit_Break;
4123 }
4124
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004125 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4127 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4128 // Check that when we have multiple declarators in the same line,
4129 // that later ones do not override the previous ones.
4130 // If we have:
4131 // int Foo, Bar;
4132 // source ranges for both start at 'int', so 'Bar' will end up overriding
4133 // 'Foo' even though the cursor location was at 'Foo'.
4134 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4135 return CXChildVisit_Break;
4136 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4137
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004138 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4140 (void)PropImp;
4141 // Check that when we have multiple @synthesize in the same line,
4142 // that later ones do not override the previous ones.
4143 // If we have:
4144 // @synthesize Foo, Bar;
4145 // source ranges for both start at '@', so 'Bar' will end up overriding
4146 // 'Foo' even though the cursor location was at 'Foo'.
4147 if (Data->VisitedObjCPropertyImplDecl)
4148 return CXChildVisit_Break;
4149 Data->VisitedObjCPropertyImplDecl = true;
4150 }
4151 }
4152
4153 if (clang_isExpression(cursor.kind) &&
4154 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004155 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 // Avoid having the cursor of an expression replace the declaration cursor
4157 // when the expression source range overlaps the declaration range.
4158 // This can happen for C++ constructor expressions whose range generally
4159 // include the variable declaration, e.g.:
4160 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4161 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4162 D->getLocation() == Data->TokenBeginLoc)
4163 return CXChildVisit_Break;
4164 }
4165 }
4166
4167 // If our current best cursor is the construction of a temporary object,
4168 // don't replace that cursor with a type reference, because we want
4169 // clang_getCursor() to point at the constructor.
4170 if (clang_isExpression(BestCursor->kind) &&
4171 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4172 cursor.kind == CXCursor_TypeRef) {
4173 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4174 // as having the actual point on the type reference.
4175 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4176 return CXChildVisit_Recurse;
4177 }
4178
4179 *BestCursor = cursor;
4180 return CXChildVisit_Recurse;
4181}
4182
4183CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004184 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004185 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004187 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004188
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004189 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4191
4192 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4193 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4194
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004195 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 CXFile SearchFile;
4197 unsigned SearchLine, SearchColumn;
4198 CXFile ResultFile;
4199 unsigned ResultLine, ResultColumn;
4200 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4201 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4202 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004203
4204 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4205 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004206 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004207 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 SearchFileName = clang_getFileName(SearchFile);
4209 ResultFileName = clang_getFileName(ResultFile);
4210 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4211 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004212 *Log << llvm::format("(%s:%d:%d) = %s",
4213 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4214 clang_getCString(KindSpelling))
4215 << llvm::format("(%s:%d:%d):%s%s",
4216 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4217 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 clang_disposeString(SearchFileName);
4219 clang_disposeString(ResultFileName);
4220 clang_disposeString(KindSpelling);
4221 clang_disposeString(USR);
4222
4223 CXCursor Definition = clang_getCursorDefinition(Result);
4224 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4225 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4226 CXString DefinitionKindSpelling
4227 = clang_getCursorKindSpelling(Definition.kind);
4228 CXFile DefinitionFile;
4229 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004230 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004231 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004233 *Log << llvm::format(" -> %s(%s:%d:%d)",
4234 clang_getCString(DefinitionKindSpelling),
4235 clang_getCString(DefinitionFileName),
4236 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 clang_disposeString(DefinitionFileName);
4238 clang_disposeString(DefinitionKindSpelling);
4239 }
4240 }
4241
4242 return Result;
4243}
4244
4245CXCursor clang_getNullCursor(void) {
4246 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4247}
4248
4249unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004250 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4251 // can't set consistently. For example, when visiting a DeclStmt we will set
4252 // it but we don't set it on the result of clang_getCursorDefinition for
4253 // a reference of the same declaration.
4254 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4255 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4256 // to provide that kind of info.
4257 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004258 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004259 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004260 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004261
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 return X == Y;
4263}
4264
4265unsigned clang_hashCursor(CXCursor C) {
4266 unsigned Index = 0;
4267 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4268 Index = 1;
4269
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004270 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 std::make_pair(C.kind, C.data[Index]));
4272}
4273
4274unsigned clang_isInvalid(enum CXCursorKind K) {
4275 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4276}
4277
4278unsigned clang_isDeclaration(enum CXCursorKind K) {
4279 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4280 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4281}
4282
4283unsigned clang_isReference(enum CXCursorKind K) {
4284 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4285}
4286
4287unsigned clang_isExpression(enum CXCursorKind K) {
4288 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4289}
4290
4291unsigned clang_isStatement(enum CXCursorKind K) {
4292 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4293}
4294
4295unsigned clang_isAttribute(enum CXCursorKind K) {
4296 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4297}
4298
4299unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4300 return K == CXCursor_TranslationUnit;
4301}
4302
4303unsigned clang_isPreprocessing(enum CXCursorKind K) {
4304 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4305}
4306
4307unsigned clang_isUnexposed(enum CXCursorKind K) {
4308 switch (K) {
4309 case CXCursor_UnexposedDecl:
4310 case CXCursor_UnexposedExpr:
4311 case CXCursor_UnexposedStmt:
4312 case CXCursor_UnexposedAttr:
4313 return true;
4314 default:
4315 return false;
4316 }
4317}
4318
4319CXCursorKind clang_getCursorKind(CXCursor C) {
4320 return C.kind;
4321}
4322
4323CXSourceLocation clang_getCursorLocation(CXCursor C) {
4324 if (clang_isReference(C.kind)) {
4325 switch (C.kind) {
4326 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004327 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 = getCursorObjCSuperClassRef(C);
4329 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4330 }
4331
4332 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004333 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 = getCursorObjCProtocolRef(C);
4335 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4336 }
4337
4338 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004339 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 = getCursorObjCClassRef(C);
4341 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4342 }
4343
4344 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004345 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4347 }
4348
4349 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004350 std::pair<const TemplateDecl *, SourceLocation> P =
4351 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4353 }
4354
4355 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004356 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4358 }
4359
4360 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004361 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4363 }
4364
4365 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004366 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4368 }
4369
4370 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004371 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!BaseSpec)
4373 return clang_getNullLocation();
4374
4375 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4376 return cxloc::translateSourceLocation(getCursorContext(C),
4377 TSInfo->getTypeLoc().getBeginLoc());
4378
4379 return cxloc::translateSourceLocation(getCursorContext(C),
4380 BaseSpec->getLocStart());
4381 }
4382
4383 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004384 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4386 }
4387
4388 case CXCursor_OverloadedDeclRef:
4389 return cxloc::translateSourceLocation(getCursorContext(C),
4390 getCursorOverloadedDeclRef(C).second);
4391
4392 default:
4393 // FIXME: Need a way to enumerate all non-reference cases.
4394 llvm_unreachable("Missed a reference kind");
4395 }
4396 }
4397
4398 if (clang_isExpression(C.kind))
4399 return cxloc::translateSourceLocation(getCursorContext(C),
4400 getLocationFromExpr(getCursorExpr(C)));
4401
4402 if (clang_isStatement(C.kind))
4403 return cxloc::translateSourceLocation(getCursorContext(C),
4404 getCursorStmt(C)->getLocStart());
4405
4406 if (C.kind == CXCursor_PreprocessingDirective) {
4407 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4408 return cxloc::translateSourceLocation(getCursorContext(C), L);
4409 }
4410
4411 if (C.kind == CXCursor_MacroExpansion) {
4412 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004413 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 return cxloc::translateSourceLocation(getCursorContext(C), L);
4415 }
4416
4417 if (C.kind == CXCursor_MacroDefinition) {
4418 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4419 return cxloc::translateSourceLocation(getCursorContext(C), L);
4420 }
4421
4422 if (C.kind == CXCursor_InclusionDirective) {
4423 SourceLocation L
4424 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4425 return cxloc::translateSourceLocation(getCursorContext(C), L);
4426 }
4427
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004428 if (clang_isAttribute(C.kind)) {
4429 SourceLocation L
4430 = cxcursor::getCursorAttr(C)->getLocation();
4431 return cxloc::translateSourceLocation(getCursorContext(C), L);
4432 }
4433
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 if (!clang_isDeclaration(C.kind))
4435 return clang_getNullLocation();
4436
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 if (!D)
4439 return clang_getNullLocation();
4440
4441 SourceLocation Loc = D->getLocation();
4442 // FIXME: Multiple variables declared in a single declaration
4443 // currently lack the information needed to correctly determine their
4444 // ranges when accounting for the type-specifier. We use context
4445 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4446 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 if (!cxcursor::isFirstInDeclGroup(C))
4449 Loc = VD->getLocation();
4450 }
4451
4452 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004453 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 Loc = MD->getSelectorStartLoc();
4455
4456 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4457}
4458
4459} // end extern "C"
4460
4461CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4462 assert(TU);
4463
4464 // Guard against an invalid SourceLocation, or we may assert in one
4465 // of the following calls.
4466 if (SLoc.isInvalid())
4467 return clang_getNullCursor();
4468
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004469 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004470
4471 // Translate the given source location to make it point at the beginning of
4472 // the token under the cursor.
4473 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4474 CXXUnit->getASTContext().getLangOpts());
4475
4476 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4477 if (SLoc.isValid()) {
4478 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4479 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4480 /*VisitPreprocessorLast=*/true,
4481 /*VisitIncludedEntities=*/false,
4482 SourceLocation(SLoc));
4483 CursorVis.visitFileRegion();
4484 }
4485
4486 return Result;
4487}
4488
4489static SourceRange getRawCursorExtent(CXCursor C) {
4490 if (clang_isReference(C.kind)) {
4491 switch (C.kind) {
4492 case CXCursor_ObjCSuperClassRef:
4493 return getCursorObjCSuperClassRef(C).second;
4494
4495 case CXCursor_ObjCProtocolRef:
4496 return getCursorObjCProtocolRef(C).second;
4497
4498 case CXCursor_ObjCClassRef:
4499 return getCursorObjCClassRef(C).second;
4500
4501 case CXCursor_TypeRef:
4502 return getCursorTypeRef(C).second;
4503
4504 case CXCursor_TemplateRef:
4505 return getCursorTemplateRef(C).second;
4506
4507 case CXCursor_NamespaceRef:
4508 return getCursorNamespaceRef(C).second;
4509
4510 case CXCursor_MemberRef:
4511 return getCursorMemberRef(C).second;
4512
4513 case CXCursor_CXXBaseSpecifier:
4514 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4515
4516 case CXCursor_LabelRef:
4517 return getCursorLabelRef(C).second;
4518
4519 case CXCursor_OverloadedDeclRef:
4520 return getCursorOverloadedDeclRef(C).second;
4521
4522 case CXCursor_VariableRef:
4523 return getCursorVariableRef(C).second;
4524
4525 default:
4526 // FIXME: Need a way to enumerate all non-reference cases.
4527 llvm_unreachable("Missed a reference kind");
4528 }
4529 }
4530
4531 if (clang_isExpression(C.kind))
4532 return getCursorExpr(C)->getSourceRange();
4533
4534 if (clang_isStatement(C.kind))
4535 return getCursorStmt(C)->getSourceRange();
4536
4537 if (clang_isAttribute(C.kind))
4538 return getCursorAttr(C)->getRange();
4539
4540 if (C.kind == CXCursor_PreprocessingDirective)
4541 return cxcursor::getCursorPreprocessingDirective(C);
4542
4543 if (C.kind == CXCursor_MacroExpansion) {
4544 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004545 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 return TU->mapRangeFromPreamble(Range);
4547 }
4548
4549 if (C.kind == CXCursor_MacroDefinition) {
4550 ASTUnit *TU = getCursorASTUnit(C);
4551 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4552 return TU->mapRangeFromPreamble(Range);
4553 }
4554
4555 if (C.kind == CXCursor_InclusionDirective) {
4556 ASTUnit *TU = getCursorASTUnit(C);
4557 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4558 return TU->mapRangeFromPreamble(Range);
4559 }
4560
4561 if (C.kind == CXCursor_TranslationUnit) {
4562 ASTUnit *TU = getCursorASTUnit(C);
4563 FileID MainID = TU->getSourceManager().getMainFileID();
4564 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4565 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4566 return SourceRange(Start, End);
4567 }
4568
4569 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004570 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 if (!D)
4572 return SourceRange();
4573
4574 SourceRange R = D->getSourceRange();
4575 // FIXME: Multiple variables declared in a single declaration
4576 // currently lack the information needed to correctly determine their
4577 // ranges when accounting for the type-specifier. We use context
4578 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4579 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 if (!cxcursor::isFirstInDeclGroup(C))
4582 R.setBegin(VD->getLocation());
4583 }
4584 return R;
4585 }
4586 return SourceRange();
4587}
4588
4589/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4590/// the decl-specifier-seq for declarations.
4591static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4592 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004593 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 if (!D)
4595 return SourceRange();
4596
4597 SourceRange R = D->getSourceRange();
4598
4599 // Adjust the start of the location for declarations preceded by
4600 // declaration specifiers.
4601 SourceLocation StartLoc;
4602 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4603 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4604 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004605 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4607 StartLoc = TI->getTypeLoc().getLocStart();
4608 }
4609
4610 if (StartLoc.isValid() && R.getBegin().isValid() &&
4611 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4612 R.setBegin(StartLoc);
4613
4614 // FIXME: Multiple variables declared in a single declaration
4615 // currently lack the information needed to correctly determine their
4616 // ranges when accounting for the type-specifier. We use context
4617 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4618 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004619 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 if (!cxcursor::isFirstInDeclGroup(C))
4621 R.setBegin(VD->getLocation());
4622 }
4623
4624 return R;
4625 }
4626
4627 return getRawCursorExtent(C);
4628}
4629
4630extern "C" {
4631
4632CXSourceRange clang_getCursorExtent(CXCursor C) {
4633 SourceRange R = getRawCursorExtent(C);
4634 if (R.isInvalid())
4635 return clang_getNullRange();
4636
4637 return cxloc::translateSourceRange(getCursorContext(C), R);
4638}
4639
4640CXCursor clang_getCursorReferenced(CXCursor C) {
4641 if (clang_isInvalid(C.kind))
4642 return clang_getNullCursor();
4643
4644 CXTranslationUnit tu = getCursorTU(C);
4645 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004646 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 if (!D)
4648 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004649 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004651 if (const ObjCPropertyImplDecl *PropImpl =
4652 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4654 return MakeCXCursor(Property, tu);
4655
4656 return C;
4657 }
4658
4659 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004660 const Expr *E = getCursorExpr(C);
4661 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 if (D) {
4663 CXCursor declCursor = MakeCXCursor(D, tu);
4664 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4665 declCursor);
4666 return declCursor;
4667 }
4668
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004669 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 return MakeCursorOverloadedDeclRef(Ovl, tu);
4671
4672 return clang_getNullCursor();
4673 }
4674
4675 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004676 const Stmt *S = getCursorStmt(C);
4677 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 if (LabelDecl *label = Goto->getLabel())
4679 if (LabelStmt *labelS = label->getStmt())
4680 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4681
4682 return clang_getNullCursor();
4683 }
4684
4685 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004686 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 return MakeMacroDefinitionCursor(Def, tu);
4688 }
4689
4690 if (!clang_isReference(C.kind))
4691 return clang_getNullCursor();
4692
4693 switch (C.kind) {
4694 case CXCursor_ObjCSuperClassRef:
4695 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4696
4697 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004698 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4699 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 return MakeCXCursor(Def, tu);
4701
4702 return MakeCXCursor(Prot, tu);
4703 }
4704
4705 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004706 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4707 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 return MakeCXCursor(Def, tu);
4709
4710 return MakeCXCursor(Class, tu);
4711 }
4712
4713 case CXCursor_TypeRef:
4714 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4715
4716 case CXCursor_TemplateRef:
4717 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4718
4719 case CXCursor_NamespaceRef:
4720 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4721
4722 case CXCursor_MemberRef:
4723 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4724
4725 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004726 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4728 tu ));
4729 }
4730
4731 case CXCursor_LabelRef:
4732 // FIXME: We end up faking the "parent" declaration here because we
4733 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004734 return MakeCXCursor(getCursorLabelRef(C).first,
4735 cxtu::getASTUnit(tu)->getASTContext()
4736 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 tu);
4738
4739 case CXCursor_OverloadedDeclRef:
4740 return C;
4741
4742 case CXCursor_VariableRef:
4743 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4744
4745 default:
4746 // We would prefer to enumerate all non-reference cursor kinds here.
4747 llvm_unreachable("Unhandled reference cursor kind");
4748 }
4749}
4750
4751CXCursor clang_getCursorDefinition(CXCursor C) {
4752 if (clang_isInvalid(C.kind))
4753 return clang_getNullCursor();
4754
4755 CXTranslationUnit TU = getCursorTU(C);
4756
4757 bool WasReference = false;
4758 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4759 C = clang_getCursorReferenced(C);
4760 WasReference = true;
4761 }
4762
4763 if (C.kind == CXCursor_MacroExpansion)
4764 return clang_getCursorReferenced(C);
4765
4766 if (!clang_isDeclaration(C.kind))
4767 return clang_getNullCursor();
4768
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 if (!D)
4771 return clang_getNullCursor();
4772
4773 switch (D->getKind()) {
4774 // Declaration kinds that don't really separate the notions of
4775 // declaration and definition.
4776 case Decl::Namespace:
4777 case Decl::Typedef:
4778 case Decl::TypeAlias:
4779 case Decl::TypeAliasTemplate:
4780 case Decl::TemplateTypeParm:
4781 case Decl::EnumConstant:
4782 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004783 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 case Decl::IndirectField:
4785 case Decl::ObjCIvar:
4786 case Decl::ObjCAtDefsField:
4787 case Decl::ImplicitParam:
4788 case Decl::ParmVar:
4789 case Decl::NonTypeTemplateParm:
4790 case Decl::TemplateTemplateParm:
4791 case Decl::ObjCCategoryImpl:
4792 case Decl::ObjCImplementation:
4793 case Decl::AccessSpec:
4794 case Decl::LinkageSpec:
4795 case Decl::ObjCPropertyImpl:
4796 case Decl::FileScopeAsm:
4797 case Decl::StaticAssert:
4798 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004799 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 case Decl::Label: // FIXME: Is this right??
4801 case Decl::ClassScopeFunctionSpecialization:
4802 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004803 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 return C;
4805
4806 // Declaration kinds that don't make any sense here, but are
4807 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004808 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 case Decl::TranslationUnit:
4810 break;
4811
4812 // Declaration kinds for which the definition is not resolvable.
4813 case Decl::UnresolvedUsingTypename:
4814 case Decl::UnresolvedUsingValue:
4815 break;
4816
4817 case Decl::UsingDirective:
4818 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4819 TU);
4820
4821 case Decl::NamespaceAlias:
4822 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4823
4824 case Decl::Enum:
4825 case Decl::Record:
4826 case Decl::CXXRecord:
4827 case Decl::ClassTemplateSpecialization:
4828 case Decl::ClassTemplatePartialSpecialization:
4829 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4830 return MakeCXCursor(Def, TU);
4831 return clang_getNullCursor();
4832
4833 case Decl::Function:
4834 case Decl::CXXMethod:
4835 case Decl::CXXConstructor:
4836 case Decl::CXXDestructor:
4837 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004838 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004840 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 return clang_getNullCursor();
4842 }
4843
Larisse Voufo39a1e502013-08-06 01:03:05 +00004844 case Decl::Var:
4845 case Decl::VarTemplateSpecialization:
4846 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004847 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 return MakeCXCursor(Def, TU);
4850 return clang_getNullCursor();
4851 }
4852
4853 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004854 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4856 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4857 return clang_getNullCursor();
4858 }
4859
4860 case Decl::ClassTemplate: {
4861 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4862 ->getDefinition())
4863 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4864 TU);
4865 return clang_getNullCursor();
4866 }
4867
Larisse Voufo39a1e502013-08-06 01:03:05 +00004868 case Decl::VarTemplate: {
4869 if (VarDecl *Def =
4870 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4871 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4872 return clang_getNullCursor();
4873 }
4874
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 case Decl::Using:
4876 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4877 D->getLocation(), TU);
4878
4879 case Decl::UsingShadow:
4880 return clang_getCursorDefinition(
4881 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4882 TU));
4883
4884 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 if (Method->isThisDeclarationADefinition())
4887 return C;
4888
4889 // Dig out the method definition in the associated
4890 // @implementation, if we have it.
4891 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4894 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4895 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4896 Method->isInstanceMethod()))
4897 if (Def->isThisDeclarationADefinition())
4898 return MakeCXCursor(Def, TU);
4899
4900 return clang_getNullCursor();
4901 }
4902
4903 case Decl::ObjCCategory:
4904 if (ObjCCategoryImplDecl *Impl
4905 = cast<ObjCCategoryDecl>(D)->getImplementation())
4906 return MakeCXCursor(Impl, TU);
4907 return clang_getNullCursor();
4908
4909 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 return MakeCXCursor(Def, TU);
4912 return clang_getNullCursor();
4913
4914 case Decl::ObjCInterface: {
4915 // There are two notions of a "definition" for an Objective-C
4916 // class: the interface and its implementation. When we resolved a
4917 // reference to an Objective-C class, produce the @interface as
4918 // the definition; when we were provided with the interface,
4919 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004920 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004922 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 return MakeCXCursor(Def, TU);
4924 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4925 return MakeCXCursor(Impl, TU);
4926 return clang_getNullCursor();
4927 }
4928
4929 case Decl::ObjCProperty:
4930 // FIXME: We don't really know where to find the
4931 // ObjCPropertyImplDecls that implement this property.
4932 return clang_getNullCursor();
4933
4934 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004935 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 return MakeCXCursor(Def, TU);
4939
4940 return clang_getNullCursor();
4941
4942 case Decl::Friend:
4943 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4944 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4945 return clang_getNullCursor();
4946
4947 case Decl::FriendTemplate:
4948 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4949 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4950 return clang_getNullCursor();
4951 }
4952
4953 return clang_getNullCursor();
4954}
4955
4956unsigned clang_isCursorDefinition(CXCursor C) {
4957 if (!clang_isDeclaration(C.kind))
4958 return 0;
4959
4960 return clang_getCursorDefinition(C) == C;
4961}
4962
4963CXCursor clang_getCanonicalCursor(CXCursor C) {
4964 if (!clang_isDeclaration(C.kind))
4965 return C;
4966
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004967 if (const Decl *D = getCursorDecl(C)) {
4968 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4970 return MakeCXCursor(CatD, getCursorTU(C));
4971
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004972 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4973 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 return MakeCXCursor(IFD, getCursorTU(C));
4975
4976 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4977 }
4978
4979 return C;
4980}
4981
4982int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4983 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4984}
4985
4986unsigned clang_getNumOverloadedDecls(CXCursor C) {
4987 if (C.kind != CXCursor_OverloadedDeclRef)
4988 return 0;
4989
4990 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return E->getNumDecls();
4993
4994 if (OverloadedTemplateStorage *S
4995 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4996 return S->size();
4997
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004998 const Decl *D = Storage.get<const Decl *>();
4999 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 return Using->shadow_size();
5001
5002 return 0;
5003}
5004
5005CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5006 if (cursor.kind != CXCursor_OverloadedDeclRef)
5007 return clang_getNullCursor();
5008
5009 if (index >= clang_getNumOverloadedDecls(cursor))
5010 return clang_getNullCursor();
5011
5012 CXTranslationUnit TU = getCursorTU(cursor);
5013 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005014 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 return MakeCXCursor(E->decls_begin()[index], TU);
5016
5017 if (OverloadedTemplateStorage *S
5018 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5019 return MakeCXCursor(S->begin()[index], TU);
5020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005021 const Decl *D = Storage.get<const Decl *>();
5022 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 // FIXME: This is, unfortunately, linear time.
5024 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5025 std::advance(Pos, index);
5026 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5027 }
5028
5029 return clang_getNullCursor();
5030}
5031
5032void clang_getDefinitionSpellingAndExtent(CXCursor C,
5033 const char **startBuf,
5034 const char **endBuf,
5035 unsigned *startLine,
5036 unsigned *startColumn,
5037 unsigned *endLine,
5038 unsigned *endColumn) {
5039 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005040 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5042
5043 SourceManager &SM = FD->getASTContext().getSourceManager();
5044 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5045 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5046 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5047 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5048 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5049 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5050}
5051
5052
5053CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5054 unsigned PieceIndex) {
5055 RefNamePieces Pieces;
5056
5057 switch (C.kind) {
5058 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005059 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5061 E->getQualifierLoc().getSourceRange());
5062 break;
5063
5064 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005065 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5067 E->getQualifierLoc().getSourceRange(),
5068 E->getOptionalExplicitTemplateArgs());
5069 break;
5070
5071 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005072 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005074 const Expr *Callee = OCE->getCallee();
5075 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 Callee = ICE->getSubExpr();
5077
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005078 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5080 DRE->getQualifierLoc().getSourceRange());
5081 }
5082 break;
5083
5084 default:
5085 break;
5086 }
5087
5088 if (Pieces.empty()) {
5089 if (PieceIndex == 0)
5090 return clang_getCursorExtent(C);
5091 } else if (PieceIndex < Pieces.size()) {
5092 SourceRange R = Pieces[PieceIndex];
5093 if (R.isValid())
5094 return cxloc::translateSourceRange(getCursorContext(C), R);
5095 }
5096
5097 return clang_getNullRange();
5098}
5099
5100void clang_enableStackTraces(void) {
5101 llvm::sys::PrintStackTraceOnErrorSignal();
5102}
5103
5104void clang_executeOnThread(void (*fn)(void*), void *user_data,
5105 unsigned stack_size) {
5106 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5107}
5108
5109} // end: extern "C"
5110
5111//===----------------------------------------------------------------------===//
5112// Token-based Operations.
5113//===----------------------------------------------------------------------===//
5114
5115/* CXToken layout:
5116 * int_data[0]: a CXTokenKind
5117 * int_data[1]: starting token location
5118 * int_data[2]: token length
5119 * int_data[3]: reserved
5120 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5121 * otherwise unused.
5122 */
5123extern "C" {
5124
5125CXTokenKind clang_getTokenKind(CXToken CXTok) {
5126 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5127}
5128
5129CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5130 switch (clang_getTokenKind(CXTok)) {
5131 case CXToken_Identifier:
5132 case CXToken_Keyword:
5133 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005134 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 ->getNameStart());
5136
5137 case CXToken_Literal: {
5138 // We have stashed the starting pointer in the ptr_data field. Use it.
5139 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005140 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 }
5142
5143 case CXToken_Punctuation:
5144 case CXToken_Comment:
5145 break;
5146 }
5147
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005148 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005149 LOG_BAD_TU(TU);
5150 return cxstring::createEmpty();
5151 }
5152
Guy Benyei11169dd2012-12-18 14:30:41 +00005153 // We have to find the starting buffer pointer the hard way, by
5154 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005155 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005157 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005158
5159 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5160 std::pair<FileID, unsigned> LocInfo
5161 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5162 bool Invalid = false;
5163 StringRef Buffer
5164 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5165 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005166 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005167
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005168 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005169}
5170
5171CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005172 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005173 LOG_BAD_TU(TU);
5174 return clang_getNullLocation();
5175 }
5176
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005177 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 if (!CXXUnit)
5179 return clang_getNullLocation();
5180
5181 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5182 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5183}
5184
5185CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005186 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005187 LOG_BAD_TU(TU);
5188 return clang_getNullRange();
5189 }
5190
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005191 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 if (!CXXUnit)
5193 return clang_getNullRange();
5194
5195 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5196 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5197}
5198
5199static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5200 SmallVectorImpl<CXToken> &CXTokens) {
5201 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5202 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005203 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005205 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005206
5207 // Cannot tokenize across files.
5208 if (BeginLocInfo.first != EndLocInfo.first)
5209 return;
5210
5211 // Create a lexer
5212 bool Invalid = false;
5213 StringRef Buffer
5214 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5215 if (Invalid)
5216 return;
5217
5218 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5219 CXXUnit->getASTContext().getLangOpts(),
5220 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5221 Lex.SetCommentRetentionState(true);
5222
5223 // Lex tokens until we hit the end of the range.
5224 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5225 Token Tok;
5226 bool previousWasAt = false;
5227 do {
5228 // Lex the next token
5229 Lex.LexFromRawLexer(Tok);
5230 if (Tok.is(tok::eof))
5231 break;
5232
5233 // Initialize the CXToken.
5234 CXToken CXTok;
5235
5236 // - Common fields
5237 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5238 CXTok.int_data[2] = Tok.getLength();
5239 CXTok.int_data[3] = 0;
5240
5241 // - Kind-specific fields
5242 if (Tok.isLiteral()) {
5243 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005244 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 } else if (Tok.is(tok::raw_identifier)) {
5246 // Lookup the identifier to determine whether we have a keyword.
5247 IdentifierInfo *II
5248 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5249
5250 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5251 CXTok.int_data[0] = CXToken_Keyword;
5252 }
5253 else {
5254 CXTok.int_data[0] = Tok.is(tok::identifier)
5255 ? CXToken_Identifier
5256 : CXToken_Keyword;
5257 }
5258 CXTok.ptr_data = II;
5259 } else if (Tok.is(tok::comment)) {
5260 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005261 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 } else {
5263 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005264 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 }
5266 CXTokens.push_back(CXTok);
5267 previousWasAt = Tok.is(tok::at);
5268 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5269}
5270
5271void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5272 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005273 LOG_FUNC_SECTION {
5274 *Log << TU << ' ' << Range;
5275 }
5276
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005278 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 if (NumTokens)
5280 *NumTokens = 0;
5281
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005282 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005283 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005284 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005285 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005286
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005287 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 if (!CXXUnit || !Tokens || !NumTokens)
5289 return;
5290
5291 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5292
5293 SourceRange R = cxloc::translateCXSourceRange(Range);
5294 if (R.isInvalid())
5295 return;
5296
5297 SmallVector<CXToken, 32> CXTokens;
5298 getTokens(CXXUnit, R, CXTokens);
5299
5300 if (CXTokens.empty())
5301 return;
5302
5303 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5304 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5305 *NumTokens = CXTokens.size();
5306}
5307
5308void clang_disposeTokens(CXTranslationUnit TU,
5309 CXToken *Tokens, unsigned NumTokens) {
5310 free(Tokens);
5311}
5312
5313} // end: extern "C"
5314
5315//===----------------------------------------------------------------------===//
5316// Token annotation APIs.
5317//===----------------------------------------------------------------------===//
5318
Guy Benyei11169dd2012-12-18 14:30:41 +00005319static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5320 CXCursor parent,
5321 CXClientData client_data);
5322static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5323 CXClientData client_data);
5324
5325namespace {
5326class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 CXToken *Tokens;
5328 CXCursor *Cursors;
5329 unsigned NumTokens;
5330 unsigned TokIdx;
5331 unsigned PreprocessingTokIdx;
5332 CursorVisitor AnnotateVis;
5333 SourceManager &SrcMgr;
5334 bool HasContextSensitiveKeywords;
5335
5336 struct PostChildrenInfo {
5337 CXCursor Cursor;
5338 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005339 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 unsigned BeforeChildrenTokenIdx;
5341 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005342 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005343
5344 CXToken &getTok(unsigned Idx) {
5345 assert(Idx < NumTokens);
5346 return Tokens[Idx];
5347 }
5348 const CXToken &getTok(unsigned Idx) const {
5349 assert(Idx < NumTokens);
5350 return Tokens[Idx];
5351 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 bool MoreTokens() const { return TokIdx < NumTokens; }
5353 unsigned NextToken() const { return TokIdx; }
5354 void AdvanceToken() { ++TokIdx; }
5355 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005356 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 }
5358 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005359 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 }
5361 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005362 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 }
5364
5365 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005366 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 SourceRange);
5368
5369public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005370 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005371 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005372 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005374 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 AnnotateTokensVisitor, this,
5376 /*VisitPreprocessorLast=*/true,
5377 /*VisitIncludedEntities=*/false,
5378 RegionOfInterest,
5379 /*VisitDeclsOnly=*/false,
5380 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005381 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 HasContextSensitiveKeywords(false) { }
5383
5384 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5385 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5386 bool postVisitChildren(CXCursor cursor);
5387 void AnnotateTokens();
5388
5389 /// \brief Determine whether the annotator saw any cursors that have
5390 /// context-sensitive keywords.
5391 bool hasContextSensitiveKeywords() const {
5392 return HasContextSensitiveKeywords;
5393 }
5394
5395 ~AnnotateTokensWorker() {
5396 assert(PostChildrenInfos.empty());
5397 }
5398};
5399}
5400
5401void AnnotateTokensWorker::AnnotateTokens() {
5402 // Walk the AST within the region of interest, annotating tokens
5403 // along the way.
5404 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005405}
Guy Benyei11169dd2012-12-18 14:30:41 +00005406
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005407static inline void updateCursorAnnotation(CXCursor &Cursor,
5408 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005409 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005411 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005412}
5413
5414/// \brief It annotates and advances tokens with a cursor until the comparison
5415//// between the cursor location and the source range is the same as
5416/// \arg compResult.
5417///
5418/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5419/// Pass RangeOverlap to annotate tokens inside a range.
5420void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5421 RangeComparisonResult compResult,
5422 SourceRange range) {
5423 while (MoreTokens()) {
5424 const unsigned I = NextToken();
5425 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005426 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5427 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005428
5429 SourceLocation TokLoc = GetTokenLoc(I);
5430 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005431 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 AdvanceToken();
5433 continue;
5434 }
5435 break;
5436 }
5437}
5438
5439/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005440/// \returns true if it advanced beyond all macro tokens, false otherwise.
5441bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 CXCursor updateC,
5443 RangeComparisonResult compResult,
5444 SourceRange range) {
5445 assert(MoreTokens());
5446 assert(isFunctionMacroToken(NextToken()) &&
5447 "Should be called only for macro arg tokens");
5448
5449 // This works differently than annotateAndAdvanceTokens; because expanded
5450 // macro arguments can have arbitrary translation-unit source order, we do not
5451 // advance the token index one by one until a token fails the range test.
5452 // We only advance once past all of the macro arg tokens if all of them
5453 // pass the range test. If one of them fails we keep the token index pointing
5454 // at the start of the macro arg tokens so that the failing token will be
5455 // annotated by a subsequent annotation try.
5456
5457 bool atLeastOneCompFail = false;
5458
5459 unsigned I = NextToken();
5460 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5461 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5462 if (TokLoc.isFileID())
5463 continue; // not macro arg token, it's parens or comma.
5464 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5465 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5466 Cursors[I] = updateC;
5467 } else
5468 atLeastOneCompFail = true;
5469 }
5470
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005471 if (atLeastOneCompFail)
5472 return false;
5473
5474 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5475 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005476}
5477
5478enum CXChildVisitResult
5479AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 SourceRange cursorRange = getRawCursorExtent(cursor);
5481 if (cursorRange.isInvalid())
5482 return CXChildVisit_Recurse;
5483
5484 if (!HasContextSensitiveKeywords) {
5485 // Objective-C properties can have context-sensitive keywords.
5486 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005487 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5489 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5490 }
5491 // Objective-C methods can have context-sensitive keywords.
5492 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5493 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005494 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5496 if (Method->getObjCDeclQualifier())
5497 HasContextSensitiveKeywords = true;
5498 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005499 for (const auto *P : Method->params()) {
5500 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 HasContextSensitiveKeywords = true;
5502 break;
5503 }
5504 }
5505 }
5506 }
5507 }
5508 // C++ methods can have context-sensitive keywords.
5509 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005510 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5512 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5513 HasContextSensitiveKeywords = true;
5514 }
5515 }
5516 // C++ classes can have context-sensitive keywords.
5517 else if (cursor.kind == CXCursor_StructDecl ||
5518 cursor.kind == CXCursor_ClassDecl ||
5519 cursor.kind == CXCursor_ClassTemplate ||
5520 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005521 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 if (D->hasAttr<FinalAttr>())
5523 HasContextSensitiveKeywords = true;
5524 }
5525 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005526
5527 // Don't override a property annotation with its getter/setter method.
5528 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5529 parent.kind == CXCursor_ObjCPropertyDecl)
5530 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005531
5532 if (clang_isPreprocessing(cursor.kind)) {
5533 // Items in the preprocessing record are kept separate from items in
5534 // declarations, so we keep a separate token index.
5535 unsigned SavedTokIdx = TokIdx;
5536 TokIdx = PreprocessingTokIdx;
5537
5538 // Skip tokens up until we catch up to the beginning of the preprocessing
5539 // entry.
5540 while (MoreTokens()) {
5541 const unsigned I = NextToken();
5542 SourceLocation TokLoc = GetTokenLoc(I);
5543 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5544 case RangeBefore:
5545 AdvanceToken();
5546 continue;
5547 case RangeAfter:
5548 case RangeOverlap:
5549 break;
5550 }
5551 break;
5552 }
5553
5554 // Look at all of the tokens within this range.
5555 while (MoreTokens()) {
5556 const unsigned I = NextToken();
5557 SourceLocation TokLoc = GetTokenLoc(I);
5558 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5559 case RangeBefore:
5560 llvm_unreachable("Infeasible");
5561 case RangeAfter:
5562 break;
5563 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005564 // For macro expansions, just note where the beginning of the macro
5565 // expansion occurs.
5566 if (cursor.kind == CXCursor_MacroExpansion) {
5567 if (TokLoc == cursorRange.getBegin())
5568 Cursors[I] = cursor;
5569 AdvanceToken();
5570 break;
5571 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005572 // We may have already annotated macro names inside macro definitions.
5573 if (Cursors[I].kind != CXCursor_MacroExpansion)
5574 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005575 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 continue;
5577 }
5578 break;
5579 }
5580
5581 // Save the preprocessing token index; restore the non-preprocessing
5582 // token index.
5583 PreprocessingTokIdx = TokIdx;
5584 TokIdx = SavedTokIdx;
5585 return CXChildVisit_Recurse;
5586 }
5587
5588 if (cursorRange.isInvalid())
5589 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005590
5591 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 const enum CXCursorKind K = clang_getCursorKind(parent);
5594 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005595 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5596 // Attributes are annotated out-of-order, skip tokens until we reach it.
5597 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 ? clang_getNullCursor() : parent;
5599
5600 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5601
5602 // Avoid having the cursor of an expression "overwrite" the annotation of the
5603 // variable declaration that it belongs to.
5604 // This can happen for C++ constructor expressions whose range generally
5605 // include the variable declaration, e.g.:
5606 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005607 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005608 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005609 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 const unsigned I = NextToken();
5611 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5612 E->getLocStart() == D->getLocation() &&
5613 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005614 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 AdvanceToken();
5616 }
5617 }
5618 }
5619
5620 // Before recursing into the children keep some state that we are going
5621 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5622 // extra work after the child nodes are visited.
5623 // Note that we don't call VisitChildren here to avoid traversing statements
5624 // code-recursively which can blow the stack.
5625
5626 PostChildrenInfo Info;
5627 Info.Cursor = cursor;
5628 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005629 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 Info.BeforeChildrenTokenIdx = NextToken();
5631 PostChildrenInfos.push_back(Info);
5632
5633 return CXChildVisit_Recurse;
5634}
5635
5636bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5637 if (PostChildrenInfos.empty())
5638 return false;
5639 const PostChildrenInfo &Info = PostChildrenInfos.back();
5640 if (!clang_equalCursors(Info.Cursor, cursor))
5641 return false;
5642
5643 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5644 const unsigned AfterChildren = NextToken();
5645 SourceRange cursorRange = Info.CursorRange;
5646
5647 // Scan the tokens that are at the end of the cursor, but are not captured
5648 // but the child cursors.
5649 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5650
5651 // Scan the tokens that are at the beginning of the cursor, but are not
5652 // capture by the child cursors.
5653 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5654 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5655 break;
5656
5657 Cursors[I] = cursor;
5658 }
5659
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005660 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5661 // encountered the attribute cursor.
5662 if (clang_isAttribute(cursor.kind))
5663 TokIdx = Info.BeforeReachingCursorIdx;
5664
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 PostChildrenInfos.pop_back();
5666 return false;
5667}
5668
5669static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5670 CXCursor parent,
5671 CXClientData client_data) {
5672 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5673}
5674
5675static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5676 CXClientData client_data) {
5677 return static_cast<AnnotateTokensWorker*>(client_data)->
5678 postVisitChildren(cursor);
5679}
5680
5681namespace {
5682
5683/// \brief Uses the macro expansions in the preprocessing record to find
5684/// and mark tokens that are macro arguments. This info is used by the
5685/// AnnotateTokensWorker.
5686class MarkMacroArgTokensVisitor {
5687 SourceManager &SM;
5688 CXToken *Tokens;
5689 unsigned NumTokens;
5690 unsigned CurIdx;
5691
5692public:
5693 MarkMacroArgTokensVisitor(SourceManager &SM,
5694 CXToken *tokens, unsigned numTokens)
5695 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5696
5697 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5698 if (cursor.kind != CXCursor_MacroExpansion)
5699 return CXChildVisit_Continue;
5700
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005701 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 if (macroRange.getBegin() == macroRange.getEnd())
5703 return CXChildVisit_Continue; // it's not a function macro.
5704
5705 for (; CurIdx < NumTokens; ++CurIdx) {
5706 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5707 macroRange.getBegin()))
5708 break;
5709 }
5710
5711 if (CurIdx == NumTokens)
5712 return CXChildVisit_Break;
5713
5714 for (; CurIdx < NumTokens; ++CurIdx) {
5715 SourceLocation tokLoc = getTokenLoc(CurIdx);
5716 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5717 break;
5718
5719 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5720 }
5721
5722 if (CurIdx == NumTokens)
5723 return CXChildVisit_Break;
5724
5725 return CXChildVisit_Continue;
5726 }
5727
5728private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005729 CXToken &getTok(unsigned Idx) {
5730 assert(Idx < NumTokens);
5731 return Tokens[Idx];
5732 }
5733 const CXToken &getTok(unsigned Idx) const {
5734 assert(Idx < NumTokens);
5735 return Tokens[Idx];
5736 }
5737
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005739 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 }
5741
5742 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5743 // The third field is reserved and currently not used. Use it here
5744 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005745 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 }
5747};
5748
5749} // end anonymous namespace
5750
5751static CXChildVisitResult
5752MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5753 CXClientData client_data) {
5754 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5755 parent);
5756}
5757
5758namespace {
5759 struct clang_annotateTokens_Data {
5760 CXTranslationUnit TU;
5761 ASTUnit *CXXUnit;
5762 CXToken *Tokens;
5763 unsigned NumTokens;
5764 CXCursor *Cursors;
5765 };
5766}
5767
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005768/// \brief Used by \c annotatePreprocessorTokens.
5769/// \returns true if lexing was finished, false otherwise.
5770static bool lexNext(Lexer &Lex, Token &Tok,
5771 unsigned &NextIdx, unsigned NumTokens) {
5772 if (NextIdx >= NumTokens)
5773 return true;
5774
5775 ++NextIdx;
5776 Lex.LexFromRawLexer(Tok);
5777 if (Tok.is(tok::eof))
5778 return true;
5779
5780 return false;
5781}
5782
Guy Benyei11169dd2012-12-18 14:30:41 +00005783static void annotatePreprocessorTokens(CXTranslationUnit TU,
5784 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005785 CXCursor *Cursors,
5786 CXToken *Tokens,
5787 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005788 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005789
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005790 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5792 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005793 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005794 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005795 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005796
5797 if (BeginLocInfo.first != EndLocInfo.first)
5798 return;
5799
5800 StringRef Buffer;
5801 bool Invalid = false;
5802 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5803 if (Buffer.empty() || Invalid)
5804 return;
5805
5806 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5807 CXXUnit->getASTContext().getLangOpts(),
5808 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5809 Buffer.end());
5810 Lex.SetCommentRetentionState(true);
5811
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005812 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 // Lex tokens in raw mode until we hit the end of the range, to avoid
5814 // entering #includes or expanding macros.
5815 while (true) {
5816 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005817 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5818 break;
5819 unsigned TokIdx = NextIdx-1;
5820 assert(Tok.getLocation() ==
5821 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005822
5823 reprocess:
5824 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005825 // We have found a preprocessing directive. Annotate the tokens
5826 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005827 //
5828 // FIXME: Some simple tests here could identify macro definitions and
5829 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005830
5831 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005832 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5833 break;
5834
Craig Topper69186e72014-06-08 08:38:04 +00005835 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005836 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005837 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5838 break;
5839
5840 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005841 IdentifierInfo &II =
5842 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005843 SourceLocation MappedTokLoc =
5844 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5845 MI = getMacroInfo(II, MappedTokLoc, TU);
5846 }
5847 }
5848
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005850 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005851 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5852 finished = true;
5853 break;
5854 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005855 // If we are in a macro definition, check if the token was ever a
5856 // macro name and annotate it if that's the case.
5857 if (MI) {
5858 SourceLocation SaveLoc = Tok.getLocation();
5859 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5860 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5861 Tok.setLocation(SaveLoc);
5862 if (MacroDef)
5863 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5864 Tok.getLocation(), TU);
5865 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005866 } while (!Tok.isAtStartOfLine());
5867
5868 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5869 assert(TokIdx <= LastIdx);
5870 SourceLocation EndLoc =
5871 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5872 CXCursor Cursor =
5873 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5874
5875 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005876 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005877
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005878 if (finished)
5879 break;
5880 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 }
5883}
5884
5885// This gets run a separate thread to avoid stack blowout.
5886static void clang_annotateTokensImpl(void *UserData) {
5887 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5888 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5889 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5890 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5891 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5892
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005893 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005894 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5895 setThreadBackgroundPriority();
5896
5897 // Determine the region of interest, which contains all of the tokens.
5898 SourceRange RegionOfInterest;
5899 RegionOfInterest.setBegin(
5900 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5901 RegionOfInterest.setEnd(
5902 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5903 Tokens[NumTokens-1])));
5904
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 // Relex the tokens within the source range to look for preprocessing
5906 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005907 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005908
5909 // If begin location points inside a macro argument, set it to the expansion
5910 // location so we can have the full context when annotating semantically.
5911 {
5912 SourceManager &SM = CXXUnit->getSourceManager();
5913 SourceLocation Loc =
5914 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5915 if (Loc.isMacroID())
5916 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5917 }
5918
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5920 // Search and mark tokens that are macro argument expansions.
5921 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5922 Tokens, NumTokens);
5923 CursorVisitor MacroArgMarker(TU,
5924 MarkMacroArgTokensVisitorDelegate, &Visitor,
5925 /*VisitPreprocessorLast=*/true,
5926 /*VisitIncludedEntities=*/false,
5927 RegionOfInterest);
5928 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5929 }
5930
5931 // Annotate all of the source locations in the region of interest that map to
5932 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005933 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005934
5935 // FIXME: We use a ridiculous stack size here because the data-recursion
5936 // algorithm uses a large stack frame than the non-data recursive version,
5937 // and AnnotationTokensWorker currently transforms the data-recursion
5938 // algorithm back into a traditional recursion by explicitly calling
5939 // VisitChildren(). We will need to remove this explicit recursive call.
5940 W.AnnotateTokens();
5941
5942 // If we ran into any entities that involve context-sensitive keywords,
5943 // take another pass through the tokens to mark them as such.
5944 if (W.hasContextSensitiveKeywords()) {
5945 for (unsigned I = 0; I != NumTokens; ++I) {
5946 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5947 continue;
5948
5949 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5950 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005951 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5953 if (Property->getPropertyAttributesAsWritten() != 0 &&
5954 llvm::StringSwitch<bool>(II->getName())
5955 .Case("readonly", true)
5956 .Case("assign", true)
5957 .Case("unsafe_unretained", true)
5958 .Case("readwrite", true)
5959 .Case("retain", true)
5960 .Case("copy", true)
5961 .Case("nonatomic", true)
5962 .Case("atomic", true)
5963 .Case("getter", true)
5964 .Case("setter", true)
5965 .Case("strong", true)
5966 .Case("weak", true)
5967 .Default(false))
5968 Tokens[I].int_data[0] = CXToken_Keyword;
5969 }
5970 continue;
5971 }
5972
5973 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5974 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5975 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5976 if (llvm::StringSwitch<bool>(II->getName())
5977 .Case("in", true)
5978 .Case("out", true)
5979 .Case("inout", true)
5980 .Case("oneway", true)
5981 .Case("bycopy", true)
5982 .Case("byref", true)
5983 .Default(false))
5984 Tokens[I].int_data[0] = CXToken_Keyword;
5985 continue;
5986 }
5987
5988 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5989 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5990 Tokens[I].int_data[0] = CXToken_Keyword;
5991 continue;
5992 }
5993 }
5994 }
5995}
5996
5997extern "C" {
5998
5999void clang_annotateTokens(CXTranslationUnit TU,
6000 CXToken *Tokens, unsigned NumTokens,
6001 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006002 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006003 LOG_BAD_TU(TU);
6004 return;
6005 }
6006 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006007 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006009 }
6010
6011 LOG_FUNC_SECTION {
6012 *Log << TU << ' ';
6013 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6014 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6015 *Log << clang_getRange(bloc, eloc);
6016 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006017
6018 // Any token we don't specifically annotate will have a NULL cursor.
6019 CXCursor C = clang_getNullCursor();
6020 for (unsigned I = 0; I != NumTokens; ++I)
6021 Cursors[I] = C;
6022
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006023 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 if (!CXXUnit)
6025 return;
6026
6027 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6028
6029 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6030 llvm::CrashRecoveryContext CRC;
6031 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6032 GetSafetyThreadStackSize() * 2)) {
6033 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6034 }
6035}
6036
6037} // end: extern "C"
6038
6039//===----------------------------------------------------------------------===//
6040// Operations for querying linkage of a cursor.
6041//===----------------------------------------------------------------------===//
6042
6043extern "C" {
6044CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6045 if (!clang_isDeclaration(cursor.kind))
6046 return CXLinkage_Invalid;
6047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006048 const Decl *D = cxcursor::getCursorDecl(cursor);
6049 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006050 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006051 case NoLinkage:
6052 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 case InternalLinkage: return CXLinkage_Internal;
6054 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6055 case ExternalLinkage: return CXLinkage_External;
6056 };
6057
6058 return CXLinkage_Invalid;
6059}
6060} // end: extern "C"
6061
6062//===----------------------------------------------------------------------===//
6063// Operations for querying language of a cursor.
6064//===----------------------------------------------------------------------===//
6065
6066static CXLanguageKind getDeclLanguage(const Decl *D) {
6067 if (!D)
6068 return CXLanguage_C;
6069
6070 switch (D->getKind()) {
6071 default:
6072 break;
6073 case Decl::ImplicitParam:
6074 case Decl::ObjCAtDefsField:
6075 case Decl::ObjCCategory:
6076 case Decl::ObjCCategoryImpl:
6077 case Decl::ObjCCompatibleAlias:
6078 case Decl::ObjCImplementation:
6079 case Decl::ObjCInterface:
6080 case Decl::ObjCIvar:
6081 case Decl::ObjCMethod:
6082 case Decl::ObjCProperty:
6083 case Decl::ObjCPropertyImpl:
6084 case Decl::ObjCProtocol:
6085 return CXLanguage_ObjC;
6086 case Decl::CXXConstructor:
6087 case Decl::CXXConversion:
6088 case Decl::CXXDestructor:
6089 case Decl::CXXMethod:
6090 case Decl::CXXRecord:
6091 case Decl::ClassTemplate:
6092 case Decl::ClassTemplatePartialSpecialization:
6093 case Decl::ClassTemplateSpecialization:
6094 case Decl::Friend:
6095 case Decl::FriendTemplate:
6096 case Decl::FunctionTemplate:
6097 case Decl::LinkageSpec:
6098 case Decl::Namespace:
6099 case Decl::NamespaceAlias:
6100 case Decl::NonTypeTemplateParm:
6101 case Decl::StaticAssert:
6102 case Decl::TemplateTemplateParm:
6103 case Decl::TemplateTypeParm:
6104 case Decl::UnresolvedUsingTypename:
6105 case Decl::UnresolvedUsingValue:
6106 case Decl::Using:
6107 case Decl::UsingDirective:
6108 case Decl::UsingShadow:
6109 return CXLanguage_CPlusPlus;
6110 }
6111
6112 return CXLanguage_C;
6113}
6114
6115extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006116
6117static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6118 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6119 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006120
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006121 switch (D->getAvailability()) {
6122 case AR_Available:
6123 case AR_NotYetIntroduced:
6124 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006125 return getCursorAvailabilityForDecl(
6126 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006127 return CXAvailability_Available;
6128
6129 case AR_Deprecated:
6130 return CXAvailability_Deprecated;
6131
6132 case AR_Unavailable:
6133 return CXAvailability_NotAvailable;
6134 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006135
6136 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006137}
6138
Guy Benyei11169dd2012-12-18 14:30:41 +00006139enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6140 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006141 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6142 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006143
6144 return CXAvailability_Available;
6145}
6146
6147static CXVersion convertVersion(VersionTuple In) {
6148 CXVersion Out = { -1, -1, -1 };
6149 if (In.empty())
6150 return Out;
6151
6152 Out.Major = In.getMajor();
6153
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006154 Optional<unsigned> Minor = In.getMinor();
6155 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 Out.Minor = *Minor;
6157 else
6158 return Out;
6159
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006160 Optional<unsigned> Subminor = In.getSubminor();
6161 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 Out.Subminor = *Subminor;
6163
6164 return Out;
6165}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006166
6167static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6168 int *always_deprecated,
6169 CXString *deprecated_message,
6170 int *always_unavailable,
6171 CXString *unavailable_message,
6172 CXPlatformAvailability *availability,
6173 int availability_size) {
6174 bool HadAvailAttr = false;
6175 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006176 for (auto A : D->attrs()) {
6177 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006178 HadAvailAttr = true;
6179 if (always_deprecated)
6180 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006181 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006182 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006183 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006184 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006185 continue;
6186 }
6187
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006188 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006189 HadAvailAttr = true;
6190 if (always_unavailable)
6191 *always_unavailable = 1;
6192 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006193 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006194 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6195 }
6196 continue;
6197 }
6198
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006199 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006200 HadAvailAttr = true;
6201 if (N < availability_size) {
6202 availability[N].Platform
6203 = cxstring::createDup(Avail->getPlatform()->getName());
6204 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6205 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6206 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6207 availability[N].Unavailable = Avail->getUnavailable();
6208 availability[N].Message = cxstring::createDup(Avail->getMessage());
6209 }
6210 ++N;
6211 }
6212 }
6213
6214 if (!HadAvailAttr)
6215 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6216 return getCursorPlatformAvailabilityForDecl(
6217 cast<Decl>(EnumConst->getDeclContext()),
6218 always_deprecated,
6219 deprecated_message,
6220 always_unavailable,
6221 unavailable_message,
6222 availability,
6223 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006224
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006225 return N;
6226}
6227
Guy Benyei11169dd2012-12-18 14:30:41 +00006228int clang_getCursorPlatformAvailability(CXCursor cursor,
6229 int *always_deprecated,
6230 CXString *deprecated_message,
6231 int *always_unavailable,
6232 CXString *unavailable_message,
6233 CXPlatformAvailability *availability,
6234 int availability_size) {
6235 if (always_deprecated)
6236 *always_deprecated = 0;
6237 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006238 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 if (always_unavailable)
6240 *always_unavailable = 0;
6241 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006242 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006243
Guy Benyei11169dd2012-12-18 14:30:41 +00006244 if (!clang_isDeclaration(cursor.kind))
6245 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006247 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 if (!D)
6249 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006250
6251 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6252 deprecated_message,
6253 always_unavailable,
6254 unavailable_message,
6255 availability,
6256 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006257}
6258
6259void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6260 clang_disposeString(availability->Platform);
6261 clang_disposeString(availability->Message);
6262}
6263
6264CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6265 if (clang_isDeclaration(cursor.kind))
6266 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6267
6268 return CXLanguage_Invalid;
6269}
6270
6271 /// \brief If the given cursor is the "templated" declaration
6272 /// descibing a class or function template, return the class or
6273 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006274static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006275 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006276 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006278 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006279 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6280 return FunTmpl;
6281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006282 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6284 return ClassTmpl;
6285
6286 return D;
6287}
6288
6289CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6290 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006291 if (const Decl *D = getCursorDecl(cursor)) {
6292 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 if (!DC)
6294 return clang_getNullCursor();
6295
6296 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6297 getCursorTU(cursor));
6298 }
6299 }
6300
6301 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006302 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 return MakeCXCursor(D, getCursorTU(cursor));
6304 }
6305
6306 return clang_getNullCursor();
6307}
6308
6309CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6310 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006311 if (const Decl *D = getCursorDecl(cursor)) {
6312 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 if (!DC)
6314 return clang_getNullCursor();
6315
6316 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6317 getCursorTU(cursor));
6318 }
6319 }
6320
6321 // FIXME: Note that we can't easily compute the lexical context of a
6322 // statement or expression, so we return nothing.
6323 return clang_getNullCursor();
6324}
6325
6326CXFile clang_getIncludedFile(CXCursor cursor) {
6327 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006328 return nullptr;
6329
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006330 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006331 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006332}
6333
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006334unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6335 if (C.kind != CXCursor_ObjCPropertyDecl)
6336 return CXObjCPropertyAttr_noattr;
6337
6338 unsigned Result = CXObjCPropertyAttr_noattr;
6339 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6340 ObjCPropertyDecl::PropertyAttributeKind Attr =
6341 PD->getPropertyAttributesAsWritten();
6342
6343#define SET_CXOBJCPROP_ATTR(A) \
6344 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6345 Result |= CXObjCPropertyAttr_##A
6346 SET_CXOBJCPROP_ATTR(readonly);
6347 SET_CXOBJCPROP_ATTR(getter);
6348 SET_CXOBJCPROP_ATTR(assign);
6349 SET_CXOBJCPROP_ATTR(readwrite);
6350 SET_CXOBJCPROP_ATTR(retain);
6351 SET_CXOBJCPROP_ATTR(copy);
6352 SET_CXOBJCPROP_ATTR(nonatomic);
6353 SET_CXOBJCPROP_ATTR(setter);
6354 SET_CXOBJCPROP_ATTR(atomic);
6355 SET_CXOBJCPROP_ATTR(weak);
6356 SET_CXOBJCPROP_ATTR(strong);
6357 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6358#undef SET_CXOBJCPROP_ATTR
6359
6360 return Result;
6361}
6362
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006363unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6364 if (!clang_isDeclaration(C.kind))
6365 return CXObjCDeclQualifier_None;
6366
6367 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6368 const Decl *D = getCursorDecl(C);
6369 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6370 QT = MD->getObjCDeclQualifier();
6371 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6372 QT = PD->getObjCDeclQualifier();
6373 if (QT == Decl::OBJC_TQ_None)
6374 return CXObjCDeclQualifier_None;
6375
6376 unsigned Result = CXObjCDeclQualifier_None;
6377 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6378 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6379 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6380 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6381 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6382 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6383
6384 return Result;
6385}
6386
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006387unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6388 if (!clang_isDeclaration(C.kind))
6389 return 0;
6390
6391 const Decl *D = getCursorDecl(C);
6392 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6393 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6394 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6395 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6396
6397 return 0;
6398}
6399
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006400unsigned clang_Cursor_isVariadic(CXCursor C) {
6401 if (!clang_isDeclaration(C.kind))
6402 return 0;
6403
6404 const Decl *D = getCursorDecl(C);
6405 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6406 return FD->isVariadic();
6407 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6408 return MD->isVariadic();
6409
6410 return 0;
6411}
6412
Guy Benyei11169dd2012-12-18 14:30:41 +00006413CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6414 if (!clang_isDeclaration(C.kind))
6415 return clang_getNullRange();
6416
6417 const Decl *D = getCursorDecl(C);
6418 ASTContext &Context = getCursorContext(C);
6419 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6420 if (!RC)
6421 return clang_getNullRange();
6422
6423 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6424}
6425
6426CXString clang_Cursor_getRawCommentText(CXCursor C) {
6427 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006428 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006429
6430 const Decl *D = getCursorDecl(C);
6431 ASTContext &Context = getCursorContext(C);
6432 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6433 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6434 StringRef();
6435
6436 // Don't duplicate the string because RawText points directly into source
6437 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006438 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006439}
6440
6441CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6442 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006443 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006444
6445 const Decl *D = getCursorDecl(C);
6446 const ASTContext &Context = getCursorContext(C);
6447 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6448
6449 if (RC) {
6450 StringRef BriefText = RC->getBriefText(Context);
6451
6452 // Don't duplicate the string because RawComment ensures that this memory
6453 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006454 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 }
6456
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006457 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006458}
6459
Guy Benyei11169dd2012-12-18 14:30:41 +00006460CXModule clang_Cursor_getModule(CXCursor C) {
6461 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006462 if (const ImportDecl *ImportD =
6463 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 return ImportD->getImportedModule();
6465 }
6466
Craig Topper69186e72014-06-08 08:38:04 +00006467 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006468}
6469
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006470CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6471 if (isNotUsableTU(TU)) {
6472 LOG_BAD_TU(TU);
6473 return nullptr;
6474 }
6475 if (!File)
6476 return nullptr;
6477 FileEntry *FE = static_cast<FileEntry *>(File);
6478
6479 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6480 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6481 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6482
6483 if (Module *Mod = Header.getModule()) {
6484 if (Header.getRole() != ModuleMap::ExcludedHeader)
6485 return Mod;
6486 }
6487 return nullptr;
6488}
6489
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006490CXFile clang_Module_getASTFile(CXModule CXMod) {
6491 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006492 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006493 Module *Mod = static_cast<Module*>(CXMod);
6494 return const_cast<FileEntry *>(Mod->getASTFile());
6495}
6496
Guy Benyei11169dd2012-12-18 14:30:41 +00006497CXModule clang_Module_getParent(CXModule CXMod) {
6498 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006499 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 Module *Mod = static_cast<Module*>(CXMod);
6501 return Mod->Parent;
6502}
6503
6504CXString clang_Module_getName(CXModule CXMod) {
6505 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006506 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006508 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006509}
6510
6511CXString clang_Module_getFullName(CXModule CXMod) {
6512 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006513 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006514 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006515 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006516}
6517
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006518int clang_Module_isSystem(CXModule CXMod) {
6519 if (!CXMod)
6520 return 0;
6521 Module *Mod = static_cast<Module*>(CXMod);
6522 return Mod->IsSystem;
6523}
6524
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006525unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6526 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006527 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006528 LOG_BAD_TU(TU);
6529 return 0;
6530 }
6531 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 return 0;
6533 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006534 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6535 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6536 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006537}
6538
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006539CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6540 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006541 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006542 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006543 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006544 }
6545 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006546 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006548 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006549
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006550 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6551 if (Index < TopHeaders.size())
6552 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006553
Craig Topper69186e72014-06-08 08:38:04 +00006554 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006555}
6556
6557} // end: extern "C"
6558
6559//===----------------------------------------------------------------------===//
6560// C++ AST instrospection.
6561//===----------------------------------------------------------------------===//
6562
6563extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006564unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6565 if (!clang_isDeclaration(C.kind))
6566 return 0;
6567
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006568 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006569 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006570 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006571 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6572}
6573
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006574unsigned clang_CXXMethod_isConst(CXCursor C) {
6575 if (!clang_isDeclaration(C.kind))
6576 return 0;
6577
6578 const Decl *D = cxcursor::getCursorDecl(C);
6579 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006580 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006581 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6582}
6583
Guy Benyei11169dd2012-12-18 14:30:41 +00006584unsigned clang_CXXMethod_isStatic(CXCursor C) {
6585 if (!clang_isDeclaration(C.kind))
6586 return 0;
6587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006588 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006589 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006590 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 return (Method && Method->isStatic()) ? 1 : 0;
6592}
6593
6594unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6595 if (!clang_isDeclaration(C.kind))
6596 return 0;
6597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006598 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006599 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006600 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006601 return (Method && Method->isVirtual()) ? 1 : 0;
6602}
6603} // end: extern "C"
6604
6605//===----------------------------------------------------------------------===//
6606// Attribute introspection.
6607//===----------------------------------------------------------------------===//
6608
6609extern "C" {
6610CXType clang_getIBOutletCollectionType(CXCursor C) {
6611 if (C.kind != CXCursor_IBOutletCollectionAttr)
6612 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6613
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006614 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6616
6617 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6618}
6619} // end: extern "C"
6620
6621//===----------------------------------------------------------------------===//
6622// Inspecting memory usage.
6623//===----------------------------------------------------------------------===//
6624
6625typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6626
6627static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6628 enum CXTUResourceUsageKind k,
6629 unsigned long amount) {
6630 CXTUResourceUsageEntry entry = { k, amount };
6631 entries.push_back(entry);
6632}
6633
6634extern "C" {
6635
6636const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6637 const char *str = "";
6638 switch (kind) {
6639 case CXTUResourceUsage_AST:
6640 str = "ASTContext: expressions, declarations, and types";
6641 break;
6642 case CXTUResourceUsage_Identifiers:
6643 str = "ASTContext: identifiers";
6644 break;
6645 case CXTUResourceUsage_Selectors:
6646 str = "ASTContext: selectors";
6647 break;
6648 case CXTUResourceUsage_GlobalCompletionResults:
6649 str = "Code completion: cached global results";
6650 break;
6651 case CXTUResourceUsage_SourceManagerContentCache:
6652 str = "SourceManager: content cache allocator";
6653 break;
6654 case CXTUResourceUsage_AST_SideTables:
6655 str = "ASTContext: side tables";
6656 break;
6657 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6658 str = "SourceManager: malloc'ed memory buffers";
6659 break;
6660 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6661 str = "SourceManager: mmap'ed memory buffers";
6662 break;
6663 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6664 str = "ExternalASTSource: malloc'ed memory buffers";
6665 break;
6666 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6667 str = "ExternalASTSource: mmap'ed memory buffers";
6668 break;
6669 case CXTUResourceUsage_Preprocessor:
6670 str = "Preprocessor: malloc'ed memory";
6671 break;
6672 case CXTUResourceUsage_PreprocessingRecord:
6673 str = "Preprocessor: PreprocessingRecord";
6674 break;
6675 case CXTUResourceUsage_SourceManager_DataStructures:
6676 str = "SourceManager: data structures and tables";
6677 break;
6678 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6679 str = "Preprocessor: header search tables";
6680 break;
6681 }
6682 return str;
6683}
6684
6685CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006686 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006687 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006688 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 return usage;
6690 }
6691
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006692 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006693 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006694 ASTContext &astContext = astUnit->getASTContext();
6695
6696 // How much memory is used by AST nodes and types?
6697 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6698 (unsigned long) astContext.getASTAllocatedMemory());
6699
6700 // How much memory is used by identifiers?
6701 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6702 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6703
6704 // How much memory is used for selectors?
6705 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6706 (unsigned long) astContext.Selectors.getTotalMemory());
6707
6708 // How much memory is used by ASTContext's side tables?
6709 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6710 (unsigned long) astContext.getSideTableAllocatedMemory());
6711
6712 // How much memory is used for caching global code completion results?
6713 unsigned long completionBytes = 0;
6714 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006715 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 completionBytes = completionAllocator->getTotalMemory();
6717 }
6718 createCXTUResourceUsageEntry(*entries,
6719 CXTUResourceUsage_GlobalCompletionResults,
6720 completionBytes);
6721
6722 // How much memory is being used by SourceManager's content cache?
6723 createCXTUResourceUsageEntry(*entries,
6724 CXTUResourceUsage_SourceManagerContentCache,
6725 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6726
6727 // How much memory is being used by the MemoryBuffer's in SourceManager?
6728 const SourceManager::MemoryBufferSizes &srcBufs =
6729 astUnit->getSourceManager().getMemoryBufferSizes();
6730
6731 createCXTUResourceUsageEntry(*entries,
6732 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6733 (unsigned long) srcBufs.malloc_bytes);
6734 createCXTUResourceUsageEntry(*entries,
6735 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6736 (unsigned long) srcBufs.mmap_bytes);
6737 createCXTUResourceUsageEntry(*entries,
6738 CXTUResourceUsage_SourceManager_DataStructures,
6739 (unsigned long) astContext.getSourceManager()
6740 .getDataStructureSizes());
6741
6742 // How much memory is being used by the ExternalASTSource?
6743 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6744 const ExternalASTSource::MemoryBufferSizes &sizes =
6745 esrc->getMemoryBufferSizes();
6746
6747 createCXTUResourceUsageEntry(*entries,
6748 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6749 (unsigned long) sizes.malloc_bytes);
6750 createCXTUResourceUsageEntry(*entries,
6751 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6752 (unsigned long) sizes.mmap_bytes);
6753 }
6754
6755 // How much memory is being used by the Preprocessor?
6756 Preprocessor &pp = astUnit->getPreprocessor();
6757 createCXTUResourceUsageEntry(*entries,
6758 CXTUResourceUsage_Preprocessor,
6759 pp.getTotalMemory());
6760
6761 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6762 createCXTUResourceUsageEntry(*entries,
6763 CXTUResourceUsage_PreprocessingRecord,
6764 pRec->getTotalMemory());
6765 }
6766
6767 createCXTUResourceUsageEntry(*entries,
6768 CXTUResourceUsage_Preprocessor_HeaderSearch,
6769 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006770
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 CXTUResourceUsage usage = { (void*) entries.get(),
6772 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006773 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006774 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 return usage;
6776}
6777
6778void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6779 if (usage.data)
6780 delete (MemUsageEntries*) usage.data;
6781}
6782
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006783CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6784 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006785 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006786 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006787
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006788 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006789 LOG_BAD_TU(TU);
6790 return skipped;
6791 }
6792
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006793 if (!file)
6794 return skipped;
6795
6796 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6797 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6798 if (!ppRec)
6799 return skipped;
6800
6801 ASTContext &Ctx = astUnit->getASTContext();
6802 SourceManager &sm = Ctx.getSourceManager();
6803 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6804 FileID wantedFileID = sm.translateFile(fileEntry);
6805
6806 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6807 std::vector<SourceRange> wantedRanges;
6808 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6809 i != ei; ++i) {
6810 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6811 wantedRanges.push_back(*i);
6812 }
6813
6814 skipped->count = wantedRanges.size();
6815 skipped->ranges = new CXSourceRange[skipped->count];
6816 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6817 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6818
6819 return skipped;
6820}
6821
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006822void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6823 if (ranges) {
6824 delete[] ranges->ranges;
6825 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006826 }
6827}
6828
Guy Benyei11169dd2012-12-18 14:30:41 +00006829} // end extern "C"
6830
6831void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6832 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6833 for (unsigned I = 0; I != Usage.numEntries; ++I)
6834 fprintf(stderr, " %s: %lu\n",
6835 clang_getTUResourceUsageName(Usage.entries[I].kind),
6836 Usage.entries[I].amount);
6837
6838 clang_disposeCXTUResourceUsage(Usage);
6839}
6840
6841//===----------------------------------------------------------------------===//
6842// Misc. utility functions.
6843//===----------------------------------------------------------------------===//
6844
6845/// Default to using an 8 MB stack size on "safety" threads.
6846static unsigned SafetyStackThreadSize = 8 << 20;
6847
6848namespace clang {
6849
6850bool RunSafely(llvm::CrashRecoveryContext &CRC,
6851 void (*Fn)(void*), void *UserData,
6852 unsigned Size) {
6853 if (!Size)
6854 Size = GetSafetyThreadStackSize();
6855 if (Size)
6856 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6857 return CRC.RunSafely(Fn, UserData);
6858}
6859
6860unsigned GetSafetyThreadStackSize() {
6861 return SafetyStackThreadSize;
6862}
6863
6864void SetSafetyThreadStackSize(unsigned Value) {
6865 SafetyStackThreadSize = Value;
6866}
6867
6868}
6869
6870void clang::setThreadBackgroundPriority() {
6871 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6872 return;
6873
Alp Toker1a86ad22014-07-06 06:24:00 +00006874#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6876#endif
6877}
6878
6879void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6880 if (!Unit)
6881 return;
6882
6883 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6884 DEnd = Unit->stored_diag_end();
6885 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006886 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 CXString Msg = clang_formatDiagnostic(&Diag,
6888 clang_defaultDiagnosticDisplayOptions());
6889 fprintf(stderr, "%s\n", clang_getCString(Msg));
6890 clang_disposeString(Msg);
6891 }
6892#ifdef LLVM_ON_WIN32
6893 // On Windows, force a flush, since there may be multiple copies of
6894 // stderr and stdout in the file system, all with different buffers
6895 // but writing to the same device.
6896 fflush(stderr);
6897#endif
6898}
6899
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006900MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6901 SourceLocation MacroDefLoc,
6902 CXTranslationUnit TU){
6903 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006905 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006906 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006907
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006908 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006909 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006910 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006911 if (MD) {
6912 for (MacroDirective::DefInfo
6913 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6914 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6915 return Def.getMacroInfo();
6916 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917 }
6918
Craig Topper69186e72014-06-08 08:38:04 +00006919 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006920}
6921
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006922const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6923 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006924 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006925 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006926 const IdentifierInfo *II = MacroDef->getName();
6927 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006929
6930 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6931}
6932
6933MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6934 const Token &Tok,
6935 CXTranslationUnit TU) {
6936 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006937 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006938 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006940
6941 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006942 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006943 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6944 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006945 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006946
6947 // Check that the token is inside the definition and not its argument list.
6948 SourceManager &SM = Unit->getSourceManager();
6949 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006950 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006951 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006953
6954 Preprocessor &PP = Unit->getPreprocessor();
6955 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6956 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006957 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006958
Alp Toker2d57cea2014-05-17 04:53:25 +00006959 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006960 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006961 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006962
6963 // Check that the identifier is not one of the macro arguments.
6964 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006965 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006966
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006967 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6968 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006969 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006970
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006971 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006972}
6973
6974MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6975 SourceLocation Loc,
6976 CXTranslationUnit TU) {
6977 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006978 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006979
6980 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006981 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006982 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006983 Preprocessor &PP = Unit->getPreprocessor();
6984 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006985 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006986 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6987 Token Tok;
6988 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006989 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006990
6991 return checkForMacroInMacroDefinition(MI, Tok, TU);
6992}
6993
Guy Benyei11169dd2012-12-18 14:30:41 +00006994extern "C" {
6995
6996CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006997 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006998}
6999
7000} // end: extern "C"
7001
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007002Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7003 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007004 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007005 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007006 if (Unit->isMainFileAST())
7007 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007008 return *this;
7009 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007010 } else {
7011 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007012 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007013 return *this;
7014}
7015
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007016Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7017 *this << FE->getName();
7018 return *this;
7019}
7020
7021Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7022 CXString cursorName = clang_getCursorDisplayName(cursor);
7023 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7024 clang_disposeString(cursorName);
7025 return *this;
7026}
7027
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007028Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7029 CXFile File;
7030 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007031 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007032 CXString FileName = clang_getFileName(File);
7033 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7034 clang_disposeString(FileName);
7035 return *this;
7036}
7037
7038Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7039 CXSourceLocation BLoc = clang_getRangeStart(range);
7040 CXSourceLocation ELoc = clang_getRangeEnd(range);
7041
7042 CXFile BFile;
7043 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007044 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007045
7046 CXFile EFile;
7047 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007048 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007049
7050 CXString BFileName = clang_getFileName(BFile);
7051 if (BFile == EFile) {
7052 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7053 BLine, BColumn, ELine, EColumn);
7054 } else {
7055 CXString EFileName = clang_getFileName(EFile);
7056 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7057 BLine, BColumn)
7058 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7059 ELine, EColumn);
7060 clang_disposeString(EFileName);
7061 }
7062 clang_disposeString(BFileName);
7063 return *this;
7064}
7065
7066Logger &cxindex::Logger::operator<<(CXString Str) {
7067 *this << clang_getCString(Str);
7068 return *this;
7069}
7070
7071Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7072 LogOS << Fmt;
7073 return *this;
7074}
7075
Chandler Carruth37ad2582014-06-27 15:14:39 +00007076static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7077
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007078cxindex::Logger::~Logger() {
7079 LogOS.flush();
7080
Chandler Carruth37ad2582014-06-27 15:14:39 +00007081 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007082
7083 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7084
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007085 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007086 OS << "[libclang:" << Name << ':';
7087
Alp Toker1a86ad22014-07-06 06:24:00 +00007088#ifdef USE_DARWIN_THREADS
7089 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007090 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7091 OS << tid << ':';
7092#endif
7093
7094 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7095 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7096 OS << Msg.str() << '\n';
7097
7098 if (Trace) {
7099 llvm::sys::PrintStackTrace(stderr);
7100 OS << "--------------------------------------------------\n";
7101 }
7102}