blob: fc8703aface101483a39ae882a2b00fbebf3b808 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001787 case Stmt::OMPCriticalDirectiveClass:
1788 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001861 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001862 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001863 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001864 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001865 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001866 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001867 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001868 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001869 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001870 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001871 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001872 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001873 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874
Guy Benyei11169dd2012-12-18 14:30:41 +00001875private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1878 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1880 void AddStmt(const Stmt *S);
1881 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001884 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001885};
1886} // end anonyous namespace
1887
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 // 'S' should always be non-null, since it comes from the
1890 // statement we are visiting.
1891 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1892}
1893
1894void
1895EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1896 if (Qualifier)
1897 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1898}
1899
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 if (S)
1902 WL.push_back(StmtVisit(S, Parent));
1903}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 if (D)
1906 WL.push_back(DeclVisit(D, Parent, isFirst));
1907}
1908void EnqueueVisitor::
1909 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1910 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001912}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (D)
1915 WL.push_back(MemberRefVisit(D, L, Parent));
1916}
1917void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1918 if (TI)
1919 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1920 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001922 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 AddStmt(*Child);
1925 }
1926 if (size == WL.size())
1927 return;
1928 // Now reverse the entries we just added. This will match the DFS
1929 // ordering performed by the worklist.
1930 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1931 std::reverse(I, E);
1932}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001933namespace {
1934class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1935 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001936 /// \brief Process clauses with list of variables.
1937 template <typename T>
1938 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939public:
1940 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1941#define OPENMP_CLAUSE(Name, Class) \
1942 void Visit##Class(const Class *C);
1943#include "clang/Basic/OpenMPKinds.def"
1944};
1945
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001946void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1947 Visitor->AddStmt(C->getCondition());
1948}
1949
Alexey Bataev3778b602014-07-17 07:32:53 +00001950void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1951 Visitor->AddStmt(C->getCondition());
1952}
1953
Alexey Bataev568a8332014-03-06 06:15:19 +00001954void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1955 Visitor->AddStmt(C->getNumThreads());
1956}
1957
Alexey Bataev62c87d22014-03-21 04:51:18 +00001958void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1959 Visitor->AddStmt(C->getSafelen());
1960}
1961
Alexander Musman8bd31e62014-05-27 15:12:19 +00001962void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1963 Visitor->AddStmt(C->getNumForLoops());
1964}
1965
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001967
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001968void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1969
Alexey Bataev56dafe82014-06-20 07:16:17 +00001970void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1971 Visitor->AddStmt(C->getChunkSize());
1972}
1973
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001974void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1975
Alexey Bataev236070f2014-06-20 11:19:47 +00001976void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1977
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001978void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1979
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001980void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1981
Alexey Bataev756c1962013-09-24 03:17:45 +00001982template<typename T>
1983void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001984 for (const auto *I : Node->varlists())
1985 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001986}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001987
1988void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001989 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001990}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001991void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1992 const OMPFirstprivateClause *C) {
1993 VisitOMPClauseList(C);
1994}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001995void OMPClauseEnqueue::VisitOMPLastprivateClause(
1996 const OMPLastprivateClause *C) {
1997 VisitOMPClauseList(C);
1998}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001999void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002000 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002001}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002002void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2003 VisitOMPClauseList(C);
2004}
Alexander Musman8dba6642014-04-22 13:09:42 +00002005void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2006 VisitOMPClauseList(C);
2007 Visitor->AddStmt(C->getStep());
2008}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002009void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2010 VisitOMPClauseList(C);
2011 Visitor->AddStmt(C->getAlignment());
2012}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002013void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2014 VisitOMPClauseList(C);
2015}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002016void
2017OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2018 VisitOMPClauseList(C);
2019}
Alexey Bataev6125da92014-07-21 11:26:11 +00002020void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2021 VisitOMPClauseList(C);
2022}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002023}
Alexey Bataev756c1962013-09-24 03:17:45 +00002024
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002025void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2026 unsigned size = WL.size();
2027 OMPClauseEnqueue Visitor(this);
2028 Visitor.Visit(S);
2029 if (size == WL.size())
2030 return;
2031 // Now reverse the entries we just added. This will match the DFS
2032 // ordering performed by the worklist.
2033 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2034 std::reverse(I, E);
2035}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 AddDecl(B->getBlockDecl());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 EnqueueChildren(E);
2044 AddTypeLoc(E->getTypeSourceInfo());
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2047 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 E = S->body_rend(); I != E; ++I) {
2049 AddStmt(*I);
2050 }
2051}
2052void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 AddStmt(S->getSubStmt());
2055 AddDeclarationNameInfo(S);
2056 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2057 AddNestedNameSpecifierLoc(QualifierLoc);
2058}
2059
2060void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2063 AddDeclarationNameInfo(E);
2064 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2065 AddNestedNameSpecifierLoc(QualifierLoc);
2066 if (!E->isImplicitAccess())
2067 AddStmt(E->getBase());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 // Enqueue the initializer , if any.
2071 AddStmt(E->getInitializer());
2072 // Enqueue the array size, if any.
2073 AddStmt(E->getArraySize());
2074 // Enqueue the allocated type.
2075 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2076 // Enqueue the placement arguments.
2077 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2078 AddStmt(E->getPlacementArg(I-1));
2079}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2082 AddStmt(CE->getArg(I-1));
2083 AddStmt(CE->getCallee());
2084 AddStmt(CE->getArg(0));
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2087 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 // Visit the name of the type being destroyed.
2089 AddTypeLoc(E->getDestroyedTypeInfo());
2090 // Visit the scope type that looks disturbingly like the nested-name-specifier
2091 // but isn't.
2092 AddTypeLoc(E->getScopeTypeInfo());
2093 // Visit the nested-name-specifier.
2094 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2095 AddNestedNameSpecifierLoc(QualifierLoc);
2096 // Visit base expression.
2097 AddStmt(E->getBase());
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2100 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 AddTypeLoc(E->getTypeSourceInfo());
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2104 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 EnqueueChildren(E);
2106 AddTypeLoc(E->getTypeSourceInfo());
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 EnqueueChildren(E);
2110 if (E->isTypeOperand())
2111 AddTypeLoc(E->getTypeOperandSourceInfo());
2112}
2113
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2115 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 EnqueueChildren(E);
2117 AddTypeLoc(E->getTypeSourceInfo());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 if (E->isTypeOperand())
2122 AddTypeLoc(E->getTypeOperandSourceInfo());
2123}
2124
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 EnqueueChildren(S);
2127 AddDecl(S->getExceptionDecl());
2128}
2129
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 if (DR->hasExplicitTemplateArgs()) {
2132 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2133 }
2134 WL.push_back(DeclRefExprParts(DR, Parent));
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2137 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2139 AddDeclarationNameInfo(E);
2140 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 unsigned size = WL.size();
2144 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002145 for (const auto *D : S->decls()) {
2146 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 isFirst = false;
2148 }
2149 if (size == WL.size())
2150 return;
2151 // Now reverse the entries we just added. This will match the DFS
2152 // ordering performed by the worklist.
2153 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2154 std::reverse(I, E);
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 D = E->designators_rbegin(), DEnd = E->designators_rend();
2160 D != DEnd; ++D) {
2161 if (D->isFieldDesignator()) {
2162 if (FieldDecl *Field = D->getField())
2163 AddMemberRef(Field, D->getFieldLoc());
2164 continue;
2165 }
2166 if (D->isArrayDesignator()) {
2167 AddStmt(E->getArrayIndex(*D));
2168 continue;
2169 }
2170 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2171 AddStmt(E->getArrayRangeEnd(*D));
2172 AddStmt(E->getArrayRangeStart(*D));
2173 }
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 EnqueueChildren(E);
2177 AddTypeLoc(E->getTypeInfoAsWritten());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddStmt(FS->getBody());
2181 AddStmt(FS->getInc());
2182 AddStmt(FS->getCond());
2183 AddDecl(FS->getConditionVariable());
2184 AddStmt(FS->getInit());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddStmt(If->getElse());
2191 AddStmt(If->getThen());
2192 AddStmt(If->getCond());
2193 AddDecl(If->getConditionVariable());
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 // We care about the syntactic form of the initializer list, only.
2197 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2198 IE = Syntactic;
2199 EnqueueChildren(IE);
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 WL.push_back(MemberExprParts(M, Parent));
2203
2204 // If the base of the member access expression is an implicit 'this', don't
2205 // visit it.
2206 // FIXME: If we ever want to show these implicit accesses, this will be
2207 // unfortunate. However, clang_getCursor() relies on this behavior.
2208 if (!M->isImplicitAccess())
2209 AddStmt(M->getBase());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddTypeLoc(E->getEncodedTypeSourceInfo());
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 EnqueueChildren(M);
2216 AddTypeLoc(M->getClassReceiverTypeInfo());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // Visit the components of the offsetof expression.
2220 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2221 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2222 const OffsetOfNode &Node = E->getComponent(I-1);
2223 switch (Node.getKind()) {
2224 case OffsetOfNode::Array:
2225 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2226 break;
2227 case OffsetOfNode::Field:
2228 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2229 break;
2230 case OffsetOfNode::Identifier:
2231 case OffsetOfNode::Base:
2232 continue;
2233 }
2234 }
2235 // Visit the type into which we're computing the offset.
2236 AddTypeLoc(E->getTypeSourceInfo());
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2240 WL.push_back(OverloadExprParts(E, Parent));
2241}
2242void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 EnqueueChildren(E);
2245 if (E->isArgumentType())
2246 AddTypeLoc(E->getArgumentTypeInfo());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 EnqueueChildren(S);
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 AddStmt(S->getBody());
2253 AddStmt(S->getCond());
2254 AddDecl(S->getConditionVariable());
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 AddStmt(W->getBody());
2259 AddStmt(W->getCond());
2260 AddDecl(W->getConditionVariable());
2261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 for (unsigned I = E->getNumArgs(); I > 0; --I)
2265 AddTypeLoc(E->getArg(I-1));
2266}
2267
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddTypeLoc(E->getQueriedTypeSourceInfo());
2270}
2271
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 EnqueueChildren(E);
2274}
2275
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 VisitOverloadExpr(U);
2278 if (!U->isImplicitAccess())
2279 AddStmt(U->getBase());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 AddStmt(E->getSubExpr());
2283 AddTypeLoc(E->getWrittenTypeInfo());
2284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 WL.push_back(SizeOfPackExprParts(E, Parent));
2287}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 // If the opaque value has a source expression, just transparently
2290 // visit that. This is useful for (e.g.) pseudo-object expressions.
2291 if (Expr *SourceExpr = E->getSourceExpr())
2292 return Visit(SourceExpr);
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 AddStmt(E->getBody());
2296 WL.push_back(LambdaExprParts(E, Parent));
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 // Treat the expression like its syntactic form.
2300 Visit(E->getSyntacticForm());
2301}
2302
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002303void EnqueueVisitor::VisitOMPExecutableDirective(
2304 const OMPExecutableDirective *D) {
2305 EnqueueChildren(D);
2306 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2307 E = D->clauses().end();
2308 I != E; ++I)
2309 EnqueueChildren(*I);
2310}
2311
2312void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2313 VisitOMPExecutableDirective(D);
2314}
2315
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002316void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2317 VisitOMPExecutableDirective(D);
2318}
2319
Alexey Bataevf29276e2014-06-18 04:14:57 +00002320void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2321 VisitOMPExecutableDirective(D);
2322}
2323
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002324void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002328void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002332void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexander Musman80c22892014-07-17 08:54:58 +00002336void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002340void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2341 VisitOMPExecutableDirective(D);
2342 AddDeclarationNameInfo(D);
2343}
2344
Alexey Bataev4acb8592014-07-07 13:01:15 +00002345void
2346EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2347 VisitOMPExecutableDirective(D);
2348}
2349
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002350void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2351 const OMPParallelSectionsDirective *D) {
2352 VisitOMPExecutableDirective(D);
2353}
2354
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002355void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2356 VisitOMPExecutableDirective(D);
2357}
2358
Alexey Bataev68446b72014-07-18 07:47:19 +00002359void
2360EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2361 VisitOMPExecutableDirective(D);
2362}
2363
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002364void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2365 VisitOMPExecutableDirective(D);
2366}
2367
Alexey Bataev2df347a2014-07-18 10:17:07 +00002368void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2369 VisitOMPExecutableDirective(D);
2370}
2371
Alexey Bataev6125da92014-07-21 11:26:11 +00002372void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2373 VisitOMPExecutableDirective(D);
2374}
2375
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2378}
2379
2380bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2381 if (RegionOfInterest.isValid()) {
2382 SourceRange Range = getRawCursorExtent(C);
2383 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2384 return false;
2385 }
2386 return true;
2387}
2388
2389bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2390 while (!WL.empty()) {
2391 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002392 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002393
2394 // Set the Parent field, then back to its old value once we're done.
2395 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2396
2397 switch (LI.getKind()) {
2398 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002399 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002400 if (!D)
2401 continue;
2402
2403 // For now, perform default visitation for Decls.
2404 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2405 cast<DeclVisit>(&LI)->isFirst())))
2406 return true;
2407
2408 continue;
2409 }
2410 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2411 const ASTTemplateArgumentListInfo *ArgList =
2412 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2413 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2414 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2415 Arg != ArgEnd; ++Arg) {
2416 if (VisitTemplateArgumentLoc(*Arg))
2417 return true;
2418 }
2419 continue;
2420 }
2421 case VisitorJob::TypeLocVisitKind: {
2422 // Perform default visitation for TypeLocs.
2423 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2424 return true;
2425 continue;
2426 }
2427 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 if (LabelStmt *stmt = LS->getStmt()) {
2430 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2431 TU))) {
2432 return true;
2433 }
2434 }
2435 continue;
2436 }
2437
2438 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2439 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2440 if (VisitNestedNameSpecifierLoc(V->get()))
2441 return true;
2442 continue;
2443 }
2444
2445 case VisitorJob::DeclarationNameInfoVisitKind: {
2446 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2447 ->get()))
2448 return true;
2449 continue;
2450 }
2451 case VisitorJob::MemberRefVisitKind: {
2452 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2453 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2454 return true;
2455 continue;
2456 }
2457 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 if (!S)
2460 continue;
2461
2462 // Update the current cursor.
2463 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2464 if (!IsInRegionOfInterest(Cursor))
2465 continue;
2466 switch (Visitor(Cursor, Parent, ClientData)) {
2467 case CXChildVisit_Break: return true;
2468 case CXChildVisit_Continue: break;
2469 case CXChildVisit_Recurse:
2470 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002471 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 EnqueueWorkList(WL, S);
2473 break;
2474 }
2475 continue;
2476 }
2477 case VisitorJob::MemberExprPartsKind: {
2478 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002480
2481 // Visit the nested-name-specifier
2482 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2483 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2484 return true;
2485
2486 // Visit the declaration name.
2487 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2488 return true;
2489
2490 // Visit the explicitly-specified template arguments, if any.
2491 if (M->hasExplicitTemplateArgs()) {
2492 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2493 *ArgEnd = Arg + M->getNumTemplateArgs();
2494 Arg != ArgEnd; ++Arg) {
2495 if (VisitTemplateArgumentLoc(*Arg))
2496 return true;
2497 }
2498 }
2499 continue;
2500 }
2501 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 // Visit nested-name-specifier, if present.
2504 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2505 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2506 return true;
2507 // Visit declaration name.
2508 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2509 return true;
2510 continue;
2511 }
2512 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002514 // Visit the nested-name-specifier.
2515 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2516 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2517 return true;
2518 // Visit the declaration name.
2519 if (VisitDeclarationNameInfo(O->getNameInfo()))
2520 return true;
2521 // Visit the overloaded declaration reference.
2522 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2523 return true;
2524 continue;
2525 }
2526 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 NamedDecl *Pack = E->getPack();
2529 if (isa<TemplateTypeParmDecl>(Pack)) {
2530 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2531 E->getPackLoc(), TU)))
2532 return true;
2533
2534 continue;
2535 }
2536
2537 if (isa<TemplateTemplateParmDecl>(Pack)) {
2538 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2539 E->getPackLoc(), TU)))
2540 return true;
2541
2542 continue;
2543 }
2544
2545 // Non-type template parameter packs and function parameter packs are
2546 // treated like DeclRefExpr cursors.
2547 continue;
2548 }
2549
2550 case VisitorJob::LambdaExprPartsKind: {
2551 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2554 CEnd = E->explicit_capture_end();
2555 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002556 // FIXME: Lambda init-captures.
2557 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002558 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002559
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2561 C->getLocation(),
2562 TU)))
2563 return true;
2564 }
2565
2566 // Visit parameters and return type, if present.
2567 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2568 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2569 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2570 // Visit the whole type.
2571 if (Visit(TL))
2572 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002573 } else if (FunctionProtoTypeLoc Proto =
2574 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 if (E->hasExplicitParameters()) {
2576 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002577 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2578 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002579 return true;
2580 } else {
2581 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002582 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002583 return true;
2584 }
2585 }
2586 }
2587 break;
2588 }
2589
2590 case VisitorJob::PostChildrenVisitKind:
2591 if (PostChildrenVisitor(Parent, ClientData))
2592 return true;
2593 break;
2594 }
2595 }
2596 return false;
2597}
2598
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002599bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002600 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 if (!WorkListFreeList.empty()) {
2602 WL = WorkListFreeList.back();
2603 WL->clear();
2604 WorkListFreeList.pop_back();
2605 }
2606 else {
2607 WL = new VisitorWorkList();
2608 WorkListCache.push_back(WL);
2609 }
2610 EnqueueWorkList(*WL, S);
2611 bool result = RunVisitorWorkList(*WL);
2612 WorkListFreeList.push_back(WL);
2613 return result;
2614}
2615
2616namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002617typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002618RefNamePieces
2619buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2620 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2621 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2623 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2624 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2625
2626 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2627
2628 RefNamePieces Pieces;
2629
2630 if (WantQualifier && QLoc.isValid())
2631 Pieces.push_back(QLoc);
2632
2633 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2634 Pieces.push_back(NI.getLoc());
2635
2636 if (WantTemplateArgs && TemplateArgs)
2637 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2638 TemplateArgs->RAngleLoc));
2639
2640 if (Kind == DeclarationName::CXXOperatorName) {
2641 Pieces.push_back(SourceLocation::getFromRawEncoding(
2642 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2643 Pieces.push_back(SourceLocation::getFromRawEncoding(
2644 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2645 }
2646
2647 if (WantSinglePiece) {
2648 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2649 Pieces.clear();
2650 Pieces.push_back(R);
2651 }
2652
2653 return Pieces;
2654}
2655}
2656
2657//===----------------------------------------------------------------------===//
2658// Misc. API hooks.
2659//===----------------------------------------------------------------------===//
2660
Chad Rosier05c71aa2013-03-27 18:28:23 +00002661static void fatal_error_handler(void *user_data, const std::string& reason,
2662 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 // Write the result out to stderr avoiding errs() because raw_ostreams can
2664 // call report_fatal_error.
2665 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2666 ::abort();
2667}
2668
Chandler Carruth66660742014-06-27 16:37:27 +00002669namespace {
2670struct RegisterFatalErrorHandler {
2671 RegisterFatalErrorHandler() {
2672 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2673 }
2674};
2675}
2676
2677static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2678
Guy Benyei11169dd2012-12-18 14:30:41 +00002679extern "C" {
2680CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2681 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 // We use crash recovery to make some of our APIs more reliable, implicitly
2683 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002684 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2685 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002686
Chandler Carruth66660742014-06-27 16:37:27 +00002687 // Look through the managed static to trigger construction of the managed
2688 // static which registers our fatal error handler. This ensures it is only
2689 // registered once.
2690 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002691
2692 CIndexer *CIdxr = new CIndexer();
2693 if (excludeDeclarationsFromPCH)
2694 CIdxr->setOnlyLocalDecls();
2695 if (displayDiagnostics)
2696 CIdxr->setDisplayDiagnostics();
2697
2698 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2699 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2700 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2701 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2702 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2703 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2704
2705 return CIdxr;
2706}
2707
2708void clang_disposeIndex(CXIndex CIdx) {
2709 if (CIdx)
2710 delete static_cast<CIndexer *>(CIdx);
2711}
2712
2713void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2714 if (CIdx)
2715 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2716}
2717
2718unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2719 if (CIdx)
2720 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2721 return 0;
2722}
2723
2724void clang_toggleCrashRecovery(unsigned isEnabled) {
2725 if (isEnabled)
2726 llvm::CrashRecoveryContext::Enable();
2727 else
2728 llvm::CrashRecoveryContext::Disable();
2729}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002730
Guy Benyei11169dd2012-12-18 14:30:41 +00002731CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2732 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002733 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002734 enum CXErrorCode Result =
2735 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002736 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002737 assert((TU && Result == CXError_Success) ||
2738 (!TU && Result != CXError_Success));
2739 return TU;
2740}
2741
2742enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2743 const char *ast_filename,
2744 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002745 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002746 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002747
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002748 if (!CIdx || !ast_filename || !out_TU)
2749 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002750
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002751 LOG_FUNC_SECTION {
2752 *Log << ast_filename;
2753 }
2754
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2756 FileSystemOptions FileSystemOpts;
2757
2758 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002759 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002760 CXXIdx->getOnlyLocalDecls(), None,
2761 /*CaptureDiagnostics=*/true,
2762 /*AllowPCHWithCompilerErrors=*/true,
2763 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002764 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2765 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002766}
2767
2768unsigned clang_defaultEditingTranslationUnitOptions() {
2769 return CXTranslationUnit_PrecompiledPreamble |
2770 CXTranslationUnit_CacheCompletionResults;
2771}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002772
Guy Benyei11169dd2012-12-18 14:30:41 +00002773CXTranslationUnit
2774clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2775 const char *source_filename,
2776 int num_command_line_args,
2777 const char * const *command_line_args,
2778 unsigned num_unsaved_files,
2779 struct CXUnsavedFile *unsaved_files) {
2780 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2781 return clang_parseTranslationUnit(CIdx, source_filename,
2782 command_line_args, num_command_line_args,
2783 unsaved_files, num_unsaved_files,
2784 Options);
2785}
2786
2787struct ParseTranslationUnitInfo {
2788 CXIndex CIdx;
2789 const char *source_filename;
2790 const char *const *command_line_args;
2791 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002792 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002794 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002795 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002796};
2797static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002798 const ParseTranslationUnitInfo *PTUI =
2799 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002800 CXIndex CIdx = PTUI->CIdx;
2801 const char *source_filename = PTUI->source_filename;
2802 const char * const *command_line_args = PTUI->command_line_args;
2803 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002804 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002807 // Set up the initial return values.
2808 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002809 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002810
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002812 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002813 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 }
2816
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2818
2819 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2820 setThreadBackgroundPriority();
2821
2822 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2823 // FIXME: Add a flag for modules.
2824 TranslationUnitKind TUKind
2825 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002826 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 = options & CXTranslationUnit_CacheCompletionResults;
2828 bool IncludeBriefCommentsInCodeCompletion
2829 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2830 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2831 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2832
2833 // Configure the diagnostics.
2834 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002835 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002836
2837 // Recover resources if we crash before exiting this function.
2838 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2839 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002840 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002841
Ahmed Charlesb8984322014-03-07 20:03:18 +00002842 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2843 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002844
2845 // Recover resources if we crash before exiting this function.
2846 llvm::CrashRecoveryContextCleanupRegistrar<
2847 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2848
Alp Toker9d85b182014-07-07 01:23:14 +00002849 for (auto &UF : PTUI->unsaved_files) {
2850 llvm::MemoryBuffer *MB =
2851 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2852 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002853 }
2854
Ahmed Charlesb8984322014-03-07 20:03:18 +00002855 std::unique_ptr<std::vector<const char *>> Args(
2856 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002857
2858 // Recover resources if we crash before exiting this method.
2859 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2860 ArgsCleanup(Args.get());
2861
2862 // Since the Clang C library is primarily used by batch tools dealing with
2863 // (often very broken) source code, where spell-checking can have a
2864 // significant negative impact on performance (particularly when
2865 // precompiled headers are involved), we disable it by default.
2866 // Only do this if we haven't found a spell-checking-related argument.
2867 bool FoundSpellCheckingArgument = false;
2868 for (int I = 0; I != num_command_line_args; ++I) {
2869 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2870 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2871 FoundSpellCheckingArgument = true;
2872 break;
2873 }
2874 }
2875 if (!FoundSpellCheckingArgument)
2876 Args->push_back("-fno-spell-checking");
2877
2878 Args->insert(Args->end(), command_line_args,
2879 command_line_args + num_command_line_args);
2880
2881 // The 'source_filename' argument is optional. If the caller does not
2882 // specify it then it is assumed that the source file is specified
2883 // in the actual argument list.
2884 // Put the source file after command_line_args otherwise if '-x' flag is
2885 // present it will be unused.
2886 if (source_filename)
2887 Args->push_back(source_filename);
2888
2889 // Do we need the detailed preprocessing record?
2890 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2891 Args->push_back("-Xclang");
2892 Args->push_back("-detailed-preprocessing-record");
2893 }
2894
2895 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002896 std::unique_ptr<ASTUnit> ErrUnit;
2897 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002898 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002899 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2900 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2901 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2902 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2903 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2904 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002905
2906 if (NumErrors != Diags->getClient()->getNumErrors()) {
2907 // Make sure to check that 'Unit' is non-NULL.
2908 if (CXXIdx->getDisplayDiagnostics())
2909 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2910 }
2911
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002912 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2913 PTUI->result = CXError_ASTReadError;
2914 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002915 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002916 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2917 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002918}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002919
2920CXTranslationUnit
2921clang_parseTranslationUnit(CXIndex CIdx,
2922 const char *source_filename,
2923 const char *const *command_line_args,
2924 int num_command_line_args,
2925 struct CXUnsavedFile *unsaved_files,
2926 unsigned num_unsaved_files,
2927 unsigned options) {
2928 CXTranslationUnit TU;
2929 enum CXErrorCode Result = clang_parseTranslationUnit2(
2930 CIdx, source_filename, command_line_args, num_command_line_args,
2931 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002932 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002933 assert((TU && Result == CXError_Success) ||
2934 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935 return TU;
2936}
2937
2938enum CXErrorCode clang_parseTranslationUnit2(
2939 CXIndex CIdx,
2940 const char *source_filename,
2941 const char *const *command_line_args,
2942 int num_command_line_args,
2943 struct CXUnsavedFile *unsaved_files,
2944 unsigned num_unsaved_files,
2945 unsigned options,
2946 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002947 LOG_FUNC_SECTION {
2948 *Log << source_filename << ": ";
2949 for (int i = 0; i != num_command_line_args; ++i)
2950 *Log << command_line_args[i] << " ";
2951 }
2952
Alp Toker9d85b182014-07-07 01:23:14 +00002953 if (num_unsaved_files && !unsaved_files)
2954 return CXError_InvalidArguments;
2955
Alp Toker5c532982014-07-07 22:42:03 +00002956 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002957 ParseTranslationUnitInfo PTUI = {
2958 CIdx,
2959 source_filename,
2960 command_line_args,
2961 num_command_line_args,
2962 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2963 options,
2964 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002965 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 llvm::CrashRecoveryContext CRC;
2967
2968 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2969 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2970 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2971 fprintf(stderr, " 'command_line_args' : [");
2972 for (int i = 0; i != num_command_line_args; ++i) {
2973 if (i)
2974 fprintf(stderr, ", ");
2975 fprintf(stderr, "'%s'", command_line_args[i]);
2976 }
2977 fprintf(stderr, "],\n");
2978 fprintf(stderr, " 'unsaved_files' : [");
2979 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2980 if (i)
2981 fprintf(stderr, ", ");
2982 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2983 unsaved_files[i].Length);
2984 }
2985 fprintf(stderr, "],\n");
2986 fprintf(stderr, " 'options' : %d,\n", options);
2987 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988
2989 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002991 if (CXTranslationUnit *TU = PTUI.out_TU)
2992 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 }
Alp Toker5c532982014-07-07 22:42:03 +00002994
2995 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002996}
2997
2998unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2999 return CXSaveTranslationUnit_None;
3000}
3001
3002namespace {
3003
3004struct SaveTranslationUnitInfo {
3005 CXTranslationUnit TU;
3006 const char *FileName;
3007 unsigned options;
3008 CXSaveError result;
3009};
3010
3011}
3012
3013static void clang_saveTranslationUnit_Impl(void *UserData) {
3014 SaveTranslationUnitInfo *STUI =
3015 static_cast<SaveTranslationUnitInfo*>(UserData);
3016
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003017 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3019 setThreadBackgroundPriority();
3020
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003021 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003022 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3023}
3024
3025int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3026 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003027 LOG_FUNC_SECTION {
3028 *Log << TU << ' ' << FileName;
3029 }
3030
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003031 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003032 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003033 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003034 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003036 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3038 if (!CXXUnit->hasSema())
3039 return CXSaveError_InvalidTU;
3040
3041 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3042
3043 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3044 getenv("LIBCLANG_NOTHREADS")) {
3045 clang_saveTranslationUnit_Impl(&STUI);
3046
3047 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3048 PrintLibclangResourceUsage(TU);
3049
3050 return STUI.result;
3051 }
3052
3053 // We have an AST that has invalid nodes due to compiler errors.
3054 // Use a crash recovery thread for protection.
3055
3056 llvm::CrashRecoveryContext CRC;
3057
3058 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3059 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3060 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3061 fprintf(stderr, " 'options' : %d,\n", options);
3062 fprintf(stderr, "}\n");
3063
3064 return CXSaveError_Unknown;
3065
3066 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3067 PrintLibclangResourceUsage(TU);
3068 }
3069
3070 return STUI.result;
3071}
3072
3073void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3074 if (CTUnit) {
3075 // If the translation unit has been marked as unsafe to free, just discard
3076 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003077 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3078 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 return;
3080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003082 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3084 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003085 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 delete CTUnit;
3087 }
3088}
3089
3090unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3091 return CXReparse_None;
3092}
3093
3094struct ReparseTranslationUnitInfo {
3095 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003096 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003098 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003099};
3100
3101static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003102 const ReparseTranslationUnitInfo *RTUI =
3103 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003105 unsigned options = RTUI->options;
3106 (void) options;
3107
3108 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003111 RTUI->result = CXError_InvalidArguments;
3112 return;
3113 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003114
3115 // Reset the associated diagnostics.
3116 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003117 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003118
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003119 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3121 setThreadBackgroundPriority();
3122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003125
3126 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3127 new std::vector<ASTUnit::RemappedFile>());
3128
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 // Recover resources if we crash before exiting this function.
3130 llvm::CrashRecoveryContextCleanupRegistrar<
3131 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003132
3133 for (auto &UF : RTUI->unsaved_files) {
3134 llvm::MemoryBuffer *MB =
3135 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3136 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003138
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003139 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 RTUI->result = CXError_Success;
3141 else if (isASTReadError(CXXUnit))
3142 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003143}
3144
3145int clang_reparseTranslationUnit(CXTranslationUnit TU,
3146 unsigned num_unsaved_files,
3147 struct CXUnsavedFile *unsaved_files,
3148 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003149 LOG_FUNC_SECTION {
3150 *Log << TU;
3151 }
3152
Alp Toker9d85b182014-07-07 01:23:14 +00003153 if (num_unsaved_files && !unsaved_files)
3154 return CXError_InvalidArguments;
3155
Alp Toker5c532982014-07-07 22:42:03 +00003156 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003157 ReparseTranslationUnitInfo RTUI = {
3158 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003159 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003160
3161 if (getenv("LIBCLANG_NOTHREADS")) {
3162 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003163 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 }
3165
3166 llvm::CrashRecoveryContext CRC;
3167
3168 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3169 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003171 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3173 PrintLibclangResourceUsage(TU);
3174
Alp Toker5c532982014-07-07 22:42:03 +00003175 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003176}
3177
3178
3179CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003180 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003181 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003182 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003183 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003185 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003186 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003187}
3188
3189CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003190 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003191 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003192 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003193 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003194
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003195 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3197}
3198
3199} // end: extern "C"
3200
3201//===----------------------------------------------------------------------===//
3202// CXFile Operations.
3203//===----------------------------------------------------------------------===//
3204
3205extern "C" {
3206CXString clang_getFileName(CXFile SFile) {
3207 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003208 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003209
3210 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003211 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003212}
3213
3214time_t clang_getFileTime(CXFile SFile) {
3215 if (!SFile)
3216 return 0;
3217
3218 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3219 return FEnt->getModificationTime();
3220}
3221
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003222CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003223 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003224 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003225 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003226 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003227
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003228 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003229
3230 FileManager &FMgr = CXXUnit->getFileManager();
3231 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3232}
3233
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003234unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3235 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003236 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003237 LOG_BAD_TU(TU);
3238 return 0;
3239 }
3240
3241 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 return 0;
3243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003244 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 FileEntry *FEnt = static_cast<FileEntry *>(file);
3246 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3247 .isFileMultipleIncludeGuarded(FEnt);
3248}
3249
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003250int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3251 if (!file || !outID)
3252 return 1;
3253
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003254 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003255 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3256 outID->data[0] = ID.getDevice();
3257 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003258 outID->data[2] = FEnt->getModificationTime();
3259 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003260}
3261
Guy Benyei11169dd2012-12-18 14:30:41 +00003262} // end: extern "C"
3263
3264//===----------------------------------------------------------------------===//
3265// CXCursor Operations.
3266//===----------------------------------------------------------------------===//
3267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268static const Decl *getDeclFromExpr(const Stmt *E) {
3269 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 return getDeclFromExpr(CE->getSubExpr());
3271
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003272 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003274 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003278 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 if (PRE->isExplicitProperty())
3280 return PRE->getExplicitProperty();
3281 // It could be messaging both getter and setter as in:
3282 // ++myobj.myprop;
3283 // in which case prefer to associate the setter since it is less obvious
3284 // from inspecting the source that the setter is going to get called.
3285 if (PRE->isMessagingSetter())
3286 return PRE->getImplicitPropertySetter();
3287 return PRE->getImplicitPropertyGetter();
3288 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 if (Expr *Src = OVE->getSourceExpr())
3293 return getDeclFromExpr(Src);
3294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 if (!CE->isElidable())
3299 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 return OME->getMethodDecl();
3302
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003305 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3307 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003308 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3310 isa<ParmVarDecl>(SizeOfPack->getPack()))
3311 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003312
3313 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003314}
3315
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003316static SourceLocation getLocationFromExpr(const Expr *E) {
3317 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 return getLocationFromExpr(CE->getSubExpr());
3319
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003320 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003322 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003324 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003326 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003328 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003330 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 return PropRef->getLocation();
3332
3333 return E->getLocStart();
3334}
3335
3336extern "C" {
3337
3338unsigned clang_visitChildren(CXCursor parent,
3339 CXCursorVisitor visitor,
3340 CXClientData client_data) {
3341 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3342 /*VisitPreprocessorLast=*/false);
3343 return CursorVis.VisitChildren(parent);
3344}
3345
3346#ifndef __has_feature
3347#define __has_feature(x) 0
3348#endif
3349#if __has_feature(blocks)
3350typedef enum CXChildVisitResult
3351 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3352
3353static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3354 CXClientData client_data) {
3355 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3356 return block(cursor, parent);
3357}
3358#else
3359// If we are compiled with a compiler that doesn't have native blocks support,
3360// define and call the block manually, so the
3361typedef struct _CXChildVisitResult
3362{
3363 void *isa;
3364 int flags;
3365 int reserved;
3366 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3367 CXCursor);
3368} *CXCursorVisitorBlock;
3369
3370static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3371 CXClientData client_data) {
3372 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3373 return block->invoke(block, cursor, parent);
3374}
3375#endif
3376
3377
3378unsigned clang_visitChildrenWithBlock(CXCursor parent,
3379 CXCursorVisitorBlock block) {
3380 return clang_visitChildren(parent, visitWithBlock, block);
3381}
3382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003385 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003386
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003387 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003389 if (const ObjCPropertyImplDecl *PropImpl =
3390 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003394 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003398 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003402 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3406 // and returns different names. NamedDecl returns the class name and
3407 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003408 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003409
3410 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003411 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003412
3413 SmallString<1024> S;
3414 llvm::raw_svector_ostream os(S);
3415 ND->printName(os);
3416
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003417 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418}
3419
3420CXString clang_getCursorSpelling(CXCursor C) {
3421 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003422 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
3424 if (clang_isReference(C.kind)) {
3425 switch (C.kind) {
3426 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003427 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 }
3430 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003431 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 }
3434 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003435 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003437 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003440 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003444 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 assert(Type && "Missing type decl");
3446
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003447 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 getAsString());
3449 }
3450 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003451 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 assert(Template && "Missing template decl");
3453
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003454 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 }
3456
3457 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003458 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 assert(NS && "Missing namespace decl");
3460
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 }
3463
3464 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003465 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 assert(Field && "Missing member decl");
3467
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003468 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 }
3470
3471 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003472 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 assert(Label && "Missing label");
3474
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003475 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 }
3477
3478 case CXCursor_OverloadedDeclRef: {
3479 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3481 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003482 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003483 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003486 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 OverloadedTemplateStorage *Ovl
3488 = Storage.get<OverloadedTemplateStorage*>();
3489 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003490 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003491 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 }
3493
3494 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003495 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 assert(Var && "Missing variable decl");
3497
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003498 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 }
3500
3501 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003502 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 }
3504 }
3505
3506 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003507 const Expr *E = getCursorExpr(C);
3508
3509 if (C.kind == CXCursor_ObjCStringLiteral ||
3510 C.kind == CXCursor_StringLiteral) {
3511 const StringLiteral *SLit;
3512 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3513 SLit = OSL->getString();
3514 } else {
3515 SLit = cast<StringLiteral>(E);
3516 }
3517 SmallString<256> Buf;
3518 llvm::raw_svector_ostream OS(Buf);
3519 SLit->outputString(OS);
3520 return cxstring::createDup(OS.str());
3521 }
3522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 if (D)
3525 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003526 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528
3529 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003530 const Stmt *S = getCursorStmt(C);
3531 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003534 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 }
3536
3537 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 ->getNameStart());
3540
3541 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 ->getNameStart());
3544
3545 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003546 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003547
3548 if (clang_isDeclaration(C.kind))
3549 return getDeclSpelling(getCursorDecl(C));
3550
3551 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003552 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003553 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 }
3555
3556 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003557 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
3560
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003561 if (C.kind == CXCursor_PackedAttr) {
3562 return cxstring::createRef("packed");
3563 }
3564
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003565 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003566}
3567
3568CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3569 unsigned pieceIndex,
3570 unsigned options) {
3571 if (clang_Cursor_isNull(C))
3572 return clang_getNullRange();
3573
3574 ASTContext &Ctx = getCursorContext(C);
3575
3576 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003577 const Stmt *S = getCursorStmt(C);
3578 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 if (pieceIndex > 0)
3580 return clang_getNullRange();
3581 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3582 }
3583
3584 return clang_getNullRange();
3585 }
3586
3587 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003588 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3590 if (pieceIndex >= ME->getNumSelectorLocs())
3591 return clang_getNullRange();
3592 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3593 }
3594 }
3595
3596 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3597 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3600 if (pieceIndex >= MD->getNumSelectorLocs())
3601 return clang_getNullRange();
3602 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3603 }
3604 }
3605
3606 if (C.kind == CXCursor_ObjCCategoryDecl ||
3607 C.kind == CXCursor_ObjCCategoryImplDecl) {
3608 if (pieceIndex > 0)
3609 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003610 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3612 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3615 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3616 }
3617
3618 if (C.kind == CXCursor_ModuleImportDecl) {
3619 if (pieceIndex > 0)
3620 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003621 if (const ImportDecl *ImportD =
3622 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3624 if (!Locs.empty())
3625 return cxloc::translateSourceRange(Ctx,
3626 SourceRange(Locs.front(), Locs.back()));
3627 }
3628 return clang_getNullRange();
3629 }
3630
3631 // FIXME: A CXCursor_InclusionDirective should give the location of the
3632 // filename, but we don't keep track of this.
3633
3634 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3635 // but we don't keep track of this.
3636
3637 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3638 // but we don't keep track of this.
3639
3640 // Default handling, give the location of the cursor.
3641
3642 if (pieceIndex > 0)
3643 return clang_getNullRange();
3644
3645 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3646 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3647 return cxloc::translateSourceRange(Ctx, Loc);
3648}
3649
3650CXString clang_getCursorDisplayName(CXCursor C) {
3651 if (!clang_isDeclaration(C.kind))
3652 return clang_getCursorSpelling(C);
3653
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003654 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003656 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003657
3658 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003659 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 D = FunTmpl->getTemplatedDecl();
3661
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 SmallString<64> Str;
3664 llvm::raw_svector_ostream OS(Str);
3665 OS << *Function;
3666 if (Function->getPrimaryTemplate())
3667 OS << "<>";
3668 OS << "(";
3669 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3670 if (I)
3671 OS << ", ";
3672 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3673 }
3674
3675 if (Function->isVariadic()) {
3676 if (Function->getNumParams())
3677 OS << ", ";
3678 OS << "...";
3679 }
3680 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 }
3683
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003684 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 SmallString<64> Str;
3686 llvm::raw_svector_ostream OS(Str);
3687 OS << *ClassTemplate;
3688 OS << "<";
3689 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3690 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3691 if (I)
3692 OS << ", ";
3693
3694 NamedDecl *Param = Params->getParam(I);
3695 if (Param->getIdentifier()) {
3696 OS << Param->getIdentifier()->getName();
3697 continue;
3698 }
3699
3700 // There is no parameter name, which makes this tricky. Try to come up
3701 // with something useful that isn't too long.
3702 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3703 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3704 else if (NonTypeTemplateParmDecl *NTTP
3705 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3706 OS << NTTP->getType().getAsString(Policy);
3707 else
3708 OS << "template<...> class";
3709 }
3710
3711 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003712 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 }
3714
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003715 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3717 // If the type was explicitly written, use that.
3718 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003719 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003720
Benjamin Kramer9170e912013-02-22 15:46:01 +00003721 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 llvm::raw_svector_ostream OS(Str);
3723 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003724 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 ClassSpec->getTemplateArgs().data(),
3726 ClassSpec->getTemplateArgs().size(),
3727 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003728 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 }
3730
3731 return clang_getCursorSpelling(C);
3732}
3733
3734CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3735 switch (Kind) {
3736 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003864 case CXCursor_ObjCSelfExpr:
3865 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003954 case CXCursor_SEHLeaveStmt:
3955 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003984 case CXCursor_PackedAttr:
3985 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003986 case CXCursor_PureAttr:
3987 return cxstring::createRef("attribute(pure)");
3988 case CXCursor_ConstAttr:
3989 return cxstring::createRef("attribute(const)");
3990 case CXCursor_NoDuplicateAttr:
3991 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003992 case CXCursor_CUDAConstantAttr:
3993 return cxstring::createRef("attribute(constant)");
3994 case CXCursor_CUDADeviceAttr:
3995 return cxstring::createRef("attribute(device)");
3996 case CXCursor_CUDAGlobalAttr:
3997 return cxstring::createRef("attribute(global)");
3998 case CXCursor_CUDAHostAttr:
3999 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004048 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004049 return cxstring::createRef("OMPParallelDirective");
4050 case CXCursor_OMPSimdDirective:
4051 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004052 case CXCursor_OMPForDirective:
4053 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004054 case CXCursor_OMPSectionsDirective:
4055 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004056 case CXCursor_OMPSectionDirective:
4057 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004058 case CXCursor_OMPSingleDirective:
4059 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004060 case CXCursor_OMPMasterDirective:
4061 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004062 case CXCursor_OMPCriticalDirective:
4063 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004064 case CXCursor_OMPParallelForDirective:
4065 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004066 case CXCursor_OMPParallelSectionsDirective:
4067 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004068 case CXCursor_OMPTaskDirective:
4069 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004070 case CXCursor_OMPTaskyieldDirective:
4071 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004072 case CXCursor_OMPBarrierDirective:
4073 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004074 case CXCursor_OMPTaskwaitDirective:
4075 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004076 case CXCursor_OMPFlushDirective:
4077 return cxstring::createRef("OMPFlushDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 }
4079
4080 llvm_unreachable("Unhandled CXCursorKind");
4081}
4082
4083struct GetCursorData {
4084 SourceLocation TokenBeginLoc;
4085 bool PointsAtMacroArgExpansion;
4086 bool VisitedObjCPropertyImplDecl;
4087 SourceLocation VisitedDeclaratorDeclStartLoc;
4088 CXCursor &BestCursor;
4089
4090 GetCursorData(SourceManager &SM,
4091 SourceLocation tokenBegin, CXCursor &outputCursor)
4092 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4093 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4094 VisitedObjCPropertyImplDecl = false;
4095 }
4096};
4097
4098static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4099 CXCursor parent,
4100 CXClientData client_data) {
4101 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4102 CXCursor *BestCursor = &Data->BestCursor;
4103
4104 // If we point inside a macro argument we should provide info of what the
4105 // token is so use the actual cursor, don't replace it with a macro expansion
4106 // cursor.
4107 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4108 return CXChildVisit_Recurse;
4109
4110 if (clang_isDeclaration(cursor.kind)) {
4111 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004112 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4114 if (MD->isImplicit())
4115 return CXChildVisit_Break;
4116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004117 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4119 // Check that when we have multiple @class references in the same line,
4120 // that later ones do not override the previous ones.
4121 // If we have:
4122 // @class Foo, Bar;
4123 // source ranges for both start at '@', so 'Bar' will end up overriding
4124 // 'Foo' even though the cursor location was at 'Foo'.
4125 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4126 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004127 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4129 if (PrevID != ID &&
4130 !PrevID->isThisDeclarationADefinition() &&
4131 !ID->isThisDeclarationADefinition())
4132 return CXChildVisit_Break;
4133 }
4134
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004135 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4137 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4138 // Check that when we have multiple declarators in the same line,
4139 // that later ones do not override the previous ones.
4140 // If we have:
4141 // int Foo, Bar;
4142 // source ranges for both start at 'int', so 'Bar' will end up overriding
4143 // 'Foo' even though the cursor location was at 'Foo'.
4144 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4145 return CXChildVisit_Break;
4146 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4147
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004148 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4150 (void)PropImp;
4151 // Check that when we have multiple @synthesize in the same line,
4152 // that later ones do not override the previous ones.
4153 // If we have:
4154 // @synthesize Foo, Bar;
4155 // source ranges for both start at '@', so 'Bar' will end up overriding
4156 // 'Foo' even though the cursor location was at 'Foo'.
4157 if (Data->VisitedObjCPropertyImplDecl)
4158 return CXChildVisit_Break;
4159 Data->VisitedObjCPropertyImplDecl = true;
4160 }
4161 }
4162
4163 if (clang_isExpression(cursor.kind) &&
4164 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004165 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 // Avoid having the cursor of an expression replace the declaration cursor
4167 // when the expression source range overlaps the declaration range.
4168 // This can happen for C++ constructor expressions whose range generally
4169 // include the variable declaration, e.g.:
4170 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4171 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4172 D->getLocation() == Data->TokenBeginLoc)
4173 return CXChildVisit_Break;
4174 }
4175 }
4176
4177 // If our current best cursor is the construction of a temporary object,
4178 // don't replace that cursor with a type reference, because we want
4179 // clang_getCursor() to point at the constructor.
4180 if (clang_isExpression(BestCursor->kind) &&
4181 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4182 cursor.kind == CXCursor_TypeRef) {
4183 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4184 // as having the actual point on the type reference.
4185 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4186 return CXChildVisit_Recurse;
4187 }
4188
4189 *BestCursor = cursor;
4190 return CXChildVisit_Recurse;
4191}
4192
4193CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004194 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004195 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004197 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004198
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004199 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4201
4202 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4203 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4204
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004205 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 CXFile SearchFile;
4207 unsigned SearchLine, SearchColumn;
4208 CXFile ResultFile;
4209 unsigned ResultLine, ResultColumn;
4210 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4211 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4212 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004213
4214 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4215 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004216 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004217 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 SearchFileName = clang_getFileName(SearchFile);
4219 ResultFileName = clang_getFileName(ResultFile);
4220 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4221 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004222 *Log << llvm::format("(%s:%d:%d) = %s",
4223 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4224 clang_getCString(KindSpelling))
4225 << llvm::format("(%s:%d:%d):%s%s",
4226 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4227 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 clang_disposeString(SearchFileName);
4229 clang_disposeString(ResultFileName);
4230 clang_disposeString(KindSpelling);
4231 clang_disposeString(USR);
4232
4233 CXCursor Definition = clang_getCursorDefinition(Result);
4234 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4235 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4236 CXString DefinitionKindSpelling
4237 = clang_getCursorKindSpelling(Definition.kind);
4238 CXFile DefinitionFile;
4239 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004240 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004241 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004243 *Log << llvm::format(" -> %s(%s:%d:%d)",
4244 clang_getCString(DefinitionKindSpelling),
4245 clang_getCString(DefinitionFileName),
4246 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 clang_disposeString(DefinitionFileName);
4248 clang_disposeString(DefinitionKindSpelling);
4249 }
4250 }
4251
4252 return Result;
4253}
4254
4255CXCursor clang_getNullCursor(void) {
4256 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4257}
4258
4259unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004260 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4261 // can't set consistently. For example, when visiting a DeclStmt we will set
4262 // it but we don't set it on the result of clang_getCursorDefinition for
4263 // a reference of the same declaration.
4264 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4265 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4266 // to provide that kind of info.
4267 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004268 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004269 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004270 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004271
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 return X == Y;
4273}
4274
4275unsigned clang_hashCursor(CXCursor C) {
4276 unsigned Index = 0;
4277 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4278 Index = 1;
4279
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004280 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 std::make_pair(C.kind, C.data[Index]));
4282}
4283
4284unsigned clang_isInvalid(enum CXCursorKind K) {
4285 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4286}
4287
4288unsigned clang_isDeclaration(enum CXCursorKind K) {
4289 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4290 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4291}
4292
4293unsigned clang_isReference(enum CXCursorKind K) {
4294 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4295}
4296
4297unsigned clang_isExpression(enum CXCursorKind K) {
4298 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4299}
4300
4301unsigned clang_isStatement(enum CXCursorKind K) {
4302 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4303}
4304
4305unsigned clang_isAttribute(enum CXCursorKind K) {
4306 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4307}
4308
4309unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4310 return K == CXCursor_TranslationUnit;
4311}
4312
4313unsigned clang_isPreprocessing(enum CXCursorKind K) {
4314 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4315}
4316
4317unsigned clang_isUnexposed(enum CXCursorKind K) {
4318 switch (K) {
4319 case CXCursor_UnexposedDecl:
4320 case CXCursor_UnexposedExpr:
4321 case CXCursor_UnexposedStmt:
4322 case CXCursor_UnexposedAttr:
4323 return true;
4324 default:
4325 return false;
4326 }
4327}
4328
4329CXCursorKind clang_getCursorKind(CXCursor C) {
4330 return C.kind;
4331}
4332
4333CXSourceLocation clang_getCursorLocation(CXCursor C) {
4334 if (clang_isReference(C.kind)) {
4335 switch (C.kind) {
4336 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004337 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 = getCursorObjCSuperClassRef(C);
4339 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4340 }
4341
4342 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004343 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 = getCursorObjCProtocolRef(C);
4345 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4346 }
4347
4348 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004349 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 = getCursorObjCClassRef(C);
4351 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4352 }
4353
4354 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004355 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004356 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4357 }
4358
4359 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004360 std::pair<const TemplateDecl *, SourceLocation> P =
4361 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4363 }
4364
4365 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004366 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4368 }
4369
4370 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004371 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4373 }
4374
4375 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004376 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4378 }
4379
4380 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004381 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 if (!BaseSpec)
4383 return clang_getNullLocation();
4384
4385 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4386 return cxloc::translateSourceLocation(getCursorContext(C),
4387 TSInfo->getTypeLoc().getBeginLoc());
4388
4389 return cxloc::translateSourceLocation(getCursorContext(C),
4390 BaseSpec->getLocStart());
4391 }
4392
4393 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004394 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4396 }
4397
4398 case CXCursor_OverloadedDeclRef:
4399 return cxloc::translateSourceLocation(getCursorContext(C),
4400 getCursorOverloadedDeclRef(C).second);
4401
4402 default:
4403 // FIXME: Need a way to enumerate all non-reference cases.
4404 llvm_unreachable("Missed a reference kind");
4405 }
4406 }
4407
4408 if (clang_isExpression(C.kind))
4409 return cxloc::translateSourceLocation(getCursorContext(C),
4410 getLocationFromExpr(getCursorExpr(C)));
4411
4412 if (clang_isStatement(C.kind))
4413 return cxloc::translateSourceLocation(getCursorContext(C),
4414 getCursorStmt(C)->getLocStart());
4415
4416 if (C.kind == CXCursor_PreprocessingDirective) {
4417 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4418 return cxloc::translateSourceLocation(getCursorContext(C), L);
4419 }
4420
4421 if (C.kind == CXCursor_MacroExpansion) {
4422 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004423 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 return cxloc::translateSourceLocation(getCursorContext(C), L);
4425 }
4426
4427 if (C.kind == CXCursor_MacroDefinition) {
4428 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4429 return cxloc::translateSourceLocation(getCursorContext(C), L);
4430 }
4431
4432 if (C.kind == CXCursor_InclusionDirective) {
4433 SourceLocation L
4434 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4435 return cxloc::translateSourceLocation(getCursorContext(C), L);
4436 }
4437
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004438 if (clang_isAttribute(C.kind)) {
4439 SourceLocation L
4440 = cxcursor::getCursorAttr(C)->getLocation();
4441 return cxloc::translateSourceLocation(getCursorContext(C), L);
4442 }
4443
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 if (!clang_isDeclaration(C.kind))
4445 return clang_getNullLocation();
4446
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 if (!D)
4449 return clang_getNullLocation();
4450
4451 SourceLocation Loc = D->getLocation();
4452 // FIXME: Multiple variables declared in a single declaration
4453 // currently lack the information needed to correctly determine their
4454 // ranges when accounting for the type-specifier. We use context
4455 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4456 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (!cxcursor::isFirstInDeclGroup(C))
4459 Loc = VD->getLocation();
4460 }
4461
4462 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004463 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 Loc = MD->getSelectorStartLoc();
4465
4466 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4467}
4468
4469} // end extern "C"
4470
4471CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4472 assert(TU);
4473
4474 // Guard against an invalid SourceLocation, or we may assert in one
4475 // of the following calls.
4476 if (SLoc.isInvalid())
4477 return clang_getNullCursor();
4478
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004479 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004480
4481 // Translate the given source location to make it point at the beginning of
4482 // the token under the cursor.
4483 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4484 CXXUnit->getASTContext().getLangOpts());
4485
4486 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4487 if (SLoc.isValid()) {
4488 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4489 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4490 /*VisitPreprocessorLast=*/true,
4491 /*VisitIncludedEntities=*/false,
4492 SourceLocation(SLoc));
4493 CursorVis.visitFileRegion();
4494 }
4495
4496 return Result;
4497}
4498
4499static SourceRange getRawCursorExtent(CXCursor C) {
4500 if (clang_isReference(C.kind)) {
4501 switch (C.kind) {
4502 case CXCursor_ObjCSuperClassRef:
4503 return getCursorObjCSuperClassRef(C).second;
4504
4505 case CXCursor_ObjCProtocolRef:
4506 return getCursorObjCProtocolRef(C).second;
4507
4508 case CXCursor_ObjCClassRef:
4509 return getCursorObjCClassRef(C).second;
4510
4511 case CXCursor_TypeRef:
4512 return getCursorTypeRef(C).second;
4513
4514 case CXCursor_TemplateRef:
4515 return getCursorTemplateRef(C).second;
4516
4517 case CXCursor_NamespaceRef:
4518 return getCursorNamespaceRef(C).second;
4519
4520 case CXCursor_MemberRef:
4521 return getCursorMemberRef(C).second;
4522
4523 case CXCursor_CXXBaseSpecifier:
4524 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4525
4526 case CXCursor_LabelRef:
4527 return getCursorLabelRef(C).second;
4528
4529 case CXCursor_OverloadedDeclRef:
4530 return getCursorOverloadedDeclRef(C).second;
4531
4532 case CXCursor_VariableRef:
4533 return getCursorVariableRef(C).second;
4534
4535 default:
4536 // FIXME: Need a way to enumerate all non-reference cases.
4537 llvm_unreachable("Missed a reference kind");
4538 }
4539 }
4540
4541 if (clang_isExpression(C.kind))
4542 return getCursorExpr(C)->getSourceRange();
4543
4544 if (clang_isStatement(C.kind))
4545 return getCursorStmt(C)->getSourceRange();
4546
4547 if (clang_isAttribute(C.kind))
4548 return getCursorAttr(C)->getRange();
4549
4550 if (C.kind == CXCursor_PreprocessingDirective)
4551 return cxcursor::getCursorPreprocessingDirective(C);
4552
4553 if (C.kind == CXCursor_MacroExpansion) {
4554 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004555 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 return TU->mapRangeFromPreamble(Range);
4557 }
4558
4559 if (C.kind == CXCursor_MacroDefinition) {
4560 ASTUnit *TU = getCursorASTUnit(C);
4561 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4562 return TU->mapRangeFromPreamble(Range);
4563 }
4564
4565 if (C.kind == CXCursor_InclusionDirective) {
4566 ASTUnit *TU = getCursorASTUnit(C);
4567 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4568 return TU->mapRangeFromPreamble(Range);
4569 }
4570
4571 if (C.kind == CXCursor_TranslationUnit) {
4572 ASTUnit *TU = getCursorASTUnit(C);
4573 FileID MainID = TU->getSourceManager().getMainFileID();
4574 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4575 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4576 return SourceRange(Start, End);
4577 }
4578
4579 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 if (!D)
4582 return SourceRange();
4583
4584 SourceRange R = D->getSourceRange();
4585 // FIXME: Multiple variables declared in a single declaration
4586 // currently lack the information needed to correctly determine their
4587 // ranges when accounting for the type-specifier. We use context
4588 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4589 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004590 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 if (!cxcursor::isFirstInDeclGroup(C))
4592 R.setBegin(VD->getLocation());
4593 }
4594 return R;
4595 }
4596 return SourceRange();
4597}
4598
4599/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4600/// the decl-specifier-seq for declarations.
4601static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4602 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004603 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 if (!D)
4605 return SourceRange();
4606
4607 SourceRange R = D->getSourceRange();
4608
4609 // Adjust the start of the location for declarations preceded by
4610 // declaration specifiers.
4611 SourceLocation StartLoc;
4612 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4613 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4614 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004615 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4617 StartLoc = TI->getTypeLoc().getLocStart();
4618 }
4619
4620 if (StartLoc.isValid() && R.getBegin().isValid() &&
4621 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4622 R.setBegin(StartLoc);
4623
4624 // FIXME: Multiple variables declared in a single declaration
4625 // currently lack the information needed to correctly determine their
4626 // ranges when accounting for the type-specifier. We use context
4627 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4628 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004629 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 if (!cxcursor::isFirstInDeclGroup(C))
4631 R.setBegin(VD->getLocation());
4632 }
4633
4634 return R;
4635 }
4636
4637 return getRawCursorExtent(C);
4638}
4639
4640extern "C" {
4641
4642CXSourceRange clang_getCursorExtent(CXCursor C) {
4643 SourceRange R = getRawCursorExtent(C);
4644 if (R.isInvalid())
4645 return clang_getNullRange();
4646
4647 return cxloc::translateSourceRange(getCursorContext(C), R);
4648}
4649
4650CXCursor clang_getCursorReferenced(CXCursor C) {
4651 if (clang_isInvalid(C.kind))
4652 return clang_getNullCursor();
4653
4654 CXTranslationUnit tu = getCursorTU(C);
4655 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004656 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 if (!D)
4658 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004659 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004661 if (const ObjCPropertyImplDecl *PropImpl =
4662 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4664 return MakeCXCursor(Property, tu);
4665
4666 return C;
4667 }
4668
4669 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004670 const Expr *E = getCursorExpr(C);
4671 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 if (D) {
4673 CXCursor declCursor = MakeCXCursor(D, tu);
4674 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4675 declCursor);
4676 return declCursor;
4677 }
4678
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004679 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 return MakeCursorOverloadedDeclRef(Ovl, tu);
4681
4682 return clang_getNullCursor();
4683 }
4684
4685 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004686 const Stmt *S = getCursorStmt(C);
4687 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 if (LabelDecl *label = Goto->getLabel())
4689 if (LabelStmt *labelS = label->getStmt())
4690 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4691
4692 return clang_getNullCursor();
4693 }
4694
4695 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004696 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 return MakeMacroDefinitionCursor(Def, tu);
4698 }
4699
4700 if (!clang_isReference(C.kind))
4701 return clang_getNullCursor();
4702
4703 switch (C.kind) {
4704 case CXCursor_ObjCSuperClassRef:
4705 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4706
4707 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004708 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4709 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return MakeCXCursor(Def, tu);
4711
4712 return MakeCXCursor(Prot, tu);
4713 }
4714
4715 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004716 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4717 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 return MakeCXCursor(Def, tu);
4719
4720 return MakeCXCursor(Class, tu);
4721 }
4722
4723 case CXCursor_TypeRef:
4724 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4725
4726 case CXCursor_TemplateRef:
4727 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4728
4729 case CXCursor_NamespaceRef:
4730 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4731
4732 case CXCursor_MemberRef:
4733 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4734
4735 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004736 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4738 tu ));
4739 }
4740
4741 case CXCursor_LabelRef:
4742 // FIXME: We end up faking the "parent" declaration here because we
4743 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004744 return MakeCXCursor(getCursorLabelRef(C).first,
4745 cxtu::getASTUnit(tu)->getASTContext()
4746 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 tu);
4748
4749 case CXCursor_OverloadedDeclRef:
4750 return C;
4751
4752 case CXCursor_VariableRef:
4753 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4754
4755 default:
4756 // We would prefer to enumerate all non-reference cursor kinds here.
4757 llvm_unreachable("Unhandled reference cursor kind");
4758 }
4759}
4760
4761CXCursor clang_getCursorDefinition(CXCursor C) {
4762 if (clang_isInvalid(C.kind))
4763 return clang_getNullCursor();
4764
4765 CXTranslationUnit TU = getCursorTU(C);
4766
4767 bool WasReference = false;
4768 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4769 C = clang_getCursorReferenced(C);
4770 WasReference = true;
4771 }
4772
4773 if (C.kind == CXCursor_MacroExpansion)
4774 return clang_getCursorReferenced(C);
4775
4776 if (!clang_isDeclaration(C.kind))
4777 return clang_getNullCursor();
4778
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 if (!D)
4781 return clang_getNullCursor();
4782
4783 switch (D->getKind()) {
4784 // Declaration kinds that don't really separate the notions of
4785 // declaration and definition.
4786 case Decl::Namespace:
4787 case Decl::Typedef:
4788 case Decl::TypeAlias:
4789 case Decl::TypeAliasTemplate:
4790 case Decl::TemplateTypeParm:
4791 case Decl::EnumConstant:
4792 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004793 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 case Decl::IndirectField:
4795 case Decl::ObjCIvar:
4796 case Decl::ObjCAtDefsField:
4797 case Decl::ImplicitParam:
4798 case Decl::ParmVar:
4799 case Decl::NonTypeTemplateParm:
4800 case Decl::TemplateTemplateParm:
4801 case Decl::ObjCCategoryImpl:
4802 case Decl::ObjCImplementation:
4803 case Decl::AccessSpec:
4804 case Decl::LinkageSpec:
4805 case Decl::ObjCPropertyImpl:
4806 case Decl::FileScopeAsm:
4807 case Decl::StaticAssert:
4808 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004809 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 case Decl::Label: // FIXME: Is this right??
4811 case Decl::ClassScopeFunctionSpecialization:
4812 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004813 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 return C;
4815
4816 // Declaration kinds that don't make any sense here, but are
4817 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004818 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 case Decl::TranslationUnit:
4820 break;
4821
4822 // Declaration kinds for which the definition is not resolvable.
4823 case Decl::UnresolvedUsingTypename:
4824 case Decl::UnresolvedUsingValue:
4825 break;
4826
4827 case Decl::UsingDirective:
4828 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4829 TU);
4830
4831 case Decl::NamespaceAlias:
4832 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4833
4834 case Decl::Enum:
4835 case Decl::Record:
4836 case Decl::CXXRecord:
4837 case Decl::ClassTemplateSpecialization:
4838 case Decl::ClassTemplatePartialSpecialization:
4839 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4840 return MakeCXCursor(Def, TU);
4841 return clang_getNullCursor();
4842
4843 case Decl::Function:
4844 case Decl::CXXMethod:
4845 case Decl::CXXConstructor:
4846 case Decl::CXXDestructor:
4847 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004848 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004850 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return clang_getNullCursor();
4852 }
4853
Larisse Voufo39a1e502013-08-06 01:03:05 +00004854 case Decl::Var:
4855 case Decl::VarTemplateSpecialization:
4856 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 return MakeCXCursor(Def, TU);
4860 return clang_getNullCursor();
4861 }
4862
4863 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004864 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4866 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4867 return clang_getNullCursor();
4868 }
4869
4870 case Decl::ClassTemplate: {
4871 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4872 ->getDefinition())
4873 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4874 TU);
4875 return clang_getNullCursor();
4876 }
4877
Larisse Voufo39a1e502013-08-06 01:03:05 +00004878 case Decl::VarTemplate: {
4879 if (VarDecl *Def =
4880 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4881 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4882 return clang_getNullCursor();
4883 }
4884
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 case Decl::Using:
4886 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4887 D->getLocation(), TU);
4888
4889 case Decl::UsingShadow:
4890 return clang_getCursorDefinition(
4891 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4892 TU));
4893
4894 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004895 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004896 if (Method->isThisDeclarationADefinition())
4897 return C;
4898
4899 // Dig out the method definition in the associated
4900 // @implementation, if we have it.
4901 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004902 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4904 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4905 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4906 Method->isInstanceMethod()))
4907 if (Def->isThisDeclarationADefinition())
4908 return MakeCXCursor(Def, TU);
4909
4910 return clang_getNullCursor();
4911 }
4912
4913 case Decl::ObjCCategory:
4914 if (ObjCCategoryImplDecl *Impl
4915 = cast<ObjCCategoryDecl>(D)->getImplementation())
4916 return MakeCXCursor(Impl, TU);
4917 return clang_getNullCursor();
4918
4919 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004920 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 return MakeCXCursor(Def, TU);
4922 return clang_getNullCursor();
4923
4924 case Decl::ObjCInterface: {
4925 // There are two notions of a "definition" for an Objective-C
4926 // class: the interface and its implementation. When we resolved a
4927 // reference to an Objective-C class, produce the @interface as
4928 // the definition; when we were provided with the interface,
4929 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004930 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004932 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004933 return MakeCXCursor(Def, TU);
4934 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4935 return MakeCXCursor(Impl, TU);
4936 return clang_getNullCursor();
4937 }
4938
4939 case Decl::ObjCProperty:
4940 // FIXME: We don't really know where to find the
4941 // ObjCPropertyImplDecls that implement this property.
4942 return clang_getNullCursor();
4943
4944 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004945 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004947 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return MakeCXCursor(Def, TU);
4949
4950 return clang_getNullCursor();
4951
4952 case Decl::Friend:
4953 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4954 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4955 return clang_getNullCursor();
4956
4957 case Decl::FriendTemplate:
4958 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4959 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4960 return clang_getNullCursor();
4961 }
4962
4963 return clang_getNullCursor();
4964}
4965
4966unsigned clang_isCursorDefinition(CXCursor C) {
4967 if (!clang_isDeclaration(C.kind))
4968 return 0;
4969
4970 return clang_getCursorDefinition(C) == C;
4971}
4972
4973CXCursor clang_getCanonicalCursor(CXCursor C) {
4974 if (!clang_isDeclaration(C.kind))
4975 return C;
4976
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004977 if (const Decl *D = getCursorDecl(C)) {
4978 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4980 return MakeCXCursor(CatD, getCursorTU(C));
4981
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004982 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4983 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 return MakeCXCursor(IFD, getCursorTU(C));
4985
4986 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4987 }
4988
4989 return C;
4990}
4991
4992int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4993 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4994}
4995
4996unsigned clang_getNumOverloadedDecls(CXCursor C) {
4997 if (C.kind != CXCursor_OverloadedDeclRef)
4998 return 0;
4999
5000 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005001 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 return E->getNumDecls();
5003
5004 if (OverloadedTemplateStorage *S
5005 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5006 return S->size();
5007
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005008 const Decl *D = Storage.get<const Decl *>();
5009 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 return Using->shadow_size();
5011
5012 return 0;
5013}
5014
5015CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5016 if (cursor.kind != CXCursor_OverloadedDeclRef)
5017 return clang_getNullCursor();
5018
5019 if (index >= clang_getNumOverloadedDecls(cursor))
5020 return clang_getNullCursor();
5021
5022 CXTranslationUnit TU = getCursorTU(cursor);
5023 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005024 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 return MakeCXCursor(E->decls_begin()[index], TU);
5026
5027 if (OverloadedTemplateStorage *S
5028 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5029 return MakeCXCursor(S->begin()[index], TU);
5030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005031 const Decl *D = Storage.get<const Decl *>();
5032 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 // FIXME: This is, unfortunately, linear time.
5034 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5035 std::advance(Pos, index);
5036 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5037 }
5038
5039 return clang_getNullCursor();
5040}
5041
5042void clang_getDefinitionSpellingAndExtent(CXCursor C,
5043 const char **startBuf,
5044 const char **endBuf,
5045 unsigned *startLine,
5046 unsigned *startColumn,
5047 unsigned *endLine,
5048 unsigned *endColumn) {
5049 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005050 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5052
5053 SourceManager &SM = FD->getASTContext().getSourceManager();
5054 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5055 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5056 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5057 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5058 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5059 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5060}
5061
5062
5063CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5064 unsigned PieceIndex) {
5065 RefNamePieces Pieces;
5066
5067 switch (C.kind) {
5068 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005069 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005070 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5071 E->getQualifierLoc().getSourceRange());
5072 break;
5073
5074 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005075 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5077 E->getQualifierLoc().getSourceRange(),
5078 E->getOptionalExplicitTemplateArgs());
5079 break;
5080
5081 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005082 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005084 const Expr *Callee = OCE->getCallee();
5085 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 Callee = ICE->getSubExpr();
5087
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005088 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5090 DRE->getQualifierLoc().getSourceRange());
5091 }
5092 break;
5093
5094 default:
5095 break;
5096 }
5097
5098 if (Pieces.empty()) {
5099 if (PieceIndex == 0)
5100 return clang_getCursorExtent(C);
5101 } else if (PieceIndex < Pieces.size()) {
5102 SourceRange R = Pieces[PieceIndex];
5103 if (R.isValid())
5104 return cxloc::translateSourceRange(getCursorContext(C), R);
5105 }
5106
5107 return clang_getNullRange();
5108}
5109
5110void clang_enableStackTraces(void) {
5111 llvm::sys::PrintStackTraceOnErrorSignal();
5112}
5113
5114void clang_executeOnThread(void (*fn)(void*), void *user_data,
5115 unsigned stack_size) {
5116 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5117}
5118
5119} // end: extern "C"
5120
5121//===----------------------------------------------------------------------===//
5122// Token-based Operations.
5123//===----------------------------------------------------------------------===//
5124
5125/* CXToken layout:
5126 * int_data[0]: a CXTokenKind
5127 * int_data[1]: starting token location
5128 * int_data[2]: token length
5129 * int_data[3]: reserved
5130 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5131 * otherwise unused.
5132 */
5133extern "C" {
5134
5135CXTokenKind clang_getTokenKind(CXToken CXTok) {
5136 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5137}
5138
5139CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5140 switch (clang_getTokenKind(CXTok)) {
5141 case CXToken_Identifier:
5142 case CXToken_Keyword:
5143 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005144 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 ->getNameStart());
5146
5147 case CXToken_Literal: {
5148 // We have stashed the starting pointer in the ptr_data field. Use it.
5149 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005150 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 }
5152
5153 case CXToken_Punctuation:
5154 case CXToken_Comment:
5155 break;
5156 }
5157
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005158 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005159 LOG_BAD_TU(TU);
5160 return cxstring::createEmpty();
5161 }
5162
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 // We have to find the starting buffer pointer the hard way, by
5164 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005165 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005167 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005168
5169 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5170 std::pair<FileID, unsigned> LocInfo
5171 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5172 bool Invalid = false;
5173 StringRef Buffer
5174 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5175 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005176 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005177
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005178 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005179}
5180
5181CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005182 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005183 LOG_BAD_TU(TU);
5184 return clang_getNullLocation();
5185 }
5186
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005187 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 if (!CXXUnit)
5189 return clang_getNullLocation();
5190
5191 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5192 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5193}
5194
5195CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005196 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005197 LOG_BAD_TU(TU);
5198 return clang_getNullRange();
5199 }
5200
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005201 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 if (!CXXUnit)
5203 return clang_getNullRange();
5204
5205 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5206 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5207}
5208
5209static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5210 SmallVectorImpl<CXToken> &CXTokens) {
5211 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5212 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005213 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005215 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005216
5217 // Cannot tokenize across files.
5218 if (BeginLocInfo.first != EndLocInfo.first)
5219 return;
5220
5221 // Create a lexer
5222 bool Invalid = false;
5223 StringRef Buffer
5224 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5225 if (Invalid)
5226 return;
5227
5228 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5229 CXXUnit->getASTContext().getLangOpts(),
5230 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5231 Lex.SetCommentRetentionState(true);
5232
5233 // Lex tokens until we hit the end of the range.
5234 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5235 Token Tok;
5236 bool previousWasAt = false;
5237 do {
5238 // Lex the next token
5239 Lex.LexFromRawLexer(Tok);
5240 if (Tok.is(tok::eof))
5241 break;
5242
5243 // Initialize the CXToken.
5244 CXToken CXTok;
5245
5246 // - Common fields
5247 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5248 CXTok.int_data[2] = Tok.getLength();
5249 CXTok.int_data[3] = 0;
5250
5251 // - Kind-specific fields
5252 if (Tok.isLiteral()) {
5253 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005254 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 } else if (Tok.is(tok::raw_identifier)) {
5256 // Lookup the identifier to determine whether we have a keyword.
5257 IdentifierInfo *II
5258 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5259
5260 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5261 CXTok.int_data[0] = CXToken_Keyword;
5262 }
5263 else {
5264 CXTok.int_data[0] = Tok.is(tok::identifier)
5265 ? CXToken_Identifier
5266 : CXToken_Keyword;
5267 }
5268 CXTok.ptr_data = II;
5269 } else if (Tok.is(tok::comment)) {
5270 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005271 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 } else {
5273 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005274 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 }
5276 CXTokens.push_back(CXTok);
5277 previousWasAt = Tok.is(tok::at);
5278 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5279}
5280
5281void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5282 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005283 LOG_FUNC_SECTION {
5284 *Log << TU << ' ' << Range;
5285 }
5286
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005288 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 if (NumTokens)
5290 *NumTokens = 0;
5291
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005292 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005293 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005294 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005295 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005296
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005297 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 if (!CXXUnit || !Tokens || !NumTokens)
5299 return;
5300
5301 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5302
5303 SourceRange R = cxloc::translateCXSourceRange(Range);
5304 if (R.isInvalid())
5305 return;
5306
5307 SmallVector<CXToken, 32> CXTokens;
5308 getTokens(CXXUnit, R, CXTokens);
5309
5310 if (CXTokens.empty())
5311 return;
5312
5313 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5314 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5315 *NumTokens = CXTokens.size();
5316}
5317
5318void clang_disposeTokens(CXTranslationUnit TU,
5319 CXToken *Tokens, unsigned NumTokens) {
5320 free(Tokens);
5321}
5322
5323} // end: extern "C"
5324
5325//===----------------------------------------------------------------------===//
5326// Token annotation APIs.
5327//===----------------------------------------------------------------------===//
5328
Guy Benyei11169dd2012-12-18 14:30:41 +00005329static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5330 CXCursor parent,
5331 CXClientData client_data);
5332static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5333 CXClientData client_data);
5334
5335namespace {
5336class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 CXToken *Tokens;
5338 CXCursor *Cursors;
5339 unsigned NumTokens;
5340 unsigned TokIdx;
5341 unsigned PreprocessingTokIdx;
5342 CursorVisitor AnnotateVis;
5343 SourceManager &SrcMgr;
5344 bool HasContextSensitiveKeywords;
5345
5346 struct PostChildrenInfo {
5347 CXCursor Cursor;
5348 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005349 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 unsigned BeforeChildrenTokenIdx;
5351 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005352 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005353
5354 CXToken &getTok(unsigned Idx) {
5355 assert(Idx < NumTokens);
5356 return Tokens[Idx];
5357 }
5358 const CXToken &getTok(unsigned Idx) const {
5359 assert(Idx < NumTokens);
5360 return Tokens[Idx];
5361 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 bool MoreTokens() const { return TokIdx < NumTokens; }
5363 unsigned NextToken() const { return TokIdx; }
5364 void AdvanceToken() { ++TokIdx; }
5365 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005366 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 }
5368 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005369 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 }
5371 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005372 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 }
5374
5375 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005376 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 SourceRange);
5378
5379public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005380 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005381 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005382 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005384 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 AnnotateTokensVisitor, this,
5386 /*VisitPreprocessorLast=*/true,
5387 /*VisitIncludedEntities=*/false,
5388 RegionOfInterest,
5389 /*VisitDeclsOnly=*/false,
5390 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005391 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 HasContextSensitiveKeywords(false) { }
5393
5394 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5395 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5396 bool postVisitChildren(CXCursor cursor);
5397 void AnnotateTokens();
5398
5399 /// \brief Determine whether the annotator saw any cursors that have
5400 /// context-sensitive keywords.
5401 bool hasContextSensitiveKeywords() const {
5402 return HasContextSensitiveKeywords;
5403 }
5404
5405 ~AnnotateTokensWorker() {
5406 assert(PostChildrenInfos.empty());
5407 }
5408};
5409}
5410
5411void AnnotateTokensWorker::AnnotateTokens() {
5412 // Walk the AST within the region of interest, annotating tokens
5413 // along the way.
5414 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005415}
Guy Benyei11169dd2012-12-18 14:30:41 +00005416
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005417static inline void updateCursorAnnotation(CXCursor &Cursor,
5418 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005419 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005421 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005422}
5423
5424/// \brief It annotates and advances tokens with a cursor until the comparison
5425//// between the cursor location and the source range is the same as
5426/// \arg compResult.
5427///
5428/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5429/// Pass RangeOverlap to annotate tokens inside a range.
5430void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5431 RangeComparisonResult compResult,
5432 SourceRange range) {
5433 while (MoreTokens()) {
5434 const unsigned I = NextToken();
5435 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005436 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5437 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005438
5439 SourceLocation TokLoc = GetTokenLoc(I);
5440 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005441 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 AdvanceToken();
5443 continue;
5444 }
5445 break;
5446 }
5447}
5448
5449/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005450/// \returns true if it advanced beyond all macro tokens, false otherwise.
5451bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 CXCursor updateC,
5453 RangeComparisonResult compResult,
5454 SourceRange range) {
5455 assert(MoreTokens());
5456 assert(isFunctionMacroToken(NextToken()) &&
5457 "Should be called only for macro arg tokens");
5458
5459 // This works differently than annotateAndAdvanceTokens; because expanded
5460 // macro arguments can have arbitrary translation-unit source order, we do not
5461 // advance the token index one by one until a token fails the range test.
5462 // We only advance once past all of the macro arg tokens if all of them
5463 // pass the range test. If one of them fails we keep the token index pointing
5464 // at the start of the macro arg tokens so that the failing token will be
5465 // annotated by a subsequent annotation try.
5466
5467 bool atLeastOneCompFail = false;
5468
5469 unsigned I = NextToken();
5470 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5471 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5472 if (TokLoc.isFileID())
5473 continue; // not macro arg token, it's parens or comma.
5474 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5475 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5476 Cursors[I] = updateC;
5477 } else
5478 atLeastOneCompFail = true;
5479 }
5480
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005481 if (atLeastOneCompFail)
5482 return false;
5483
5484 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5485 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005486}
5487
5488enum CXChildVisitResult
5489AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 SourceRange cursorRange = getRawCursorExtent(cursor);
5491 if (cursorRange.isInvalid())
5492 return CXChildVisit_Recurse;
5493
5494 if (!HasContextSensitiveKeywords) {
5495 // Objective-C properties can have context-sensitive keywords.
5496 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005497 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5499 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5500 }
5501 // Objective-C methods can have context-sensitive keywords.
5502 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5503 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005504 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5506 if (Method->getObjCDeclQualifier())
5507 HasContextSensitiveKeywords = true;
5508 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005509 for (const auto *P : Method->params()) {
5510 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 HasContextSensitiveKeywords = true;
5512 break;
5513 }
5514 }
5515 }
5516 }
5517 }
5518 // C++ methods can have context-sensitive keywords.
5519 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005520 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5522 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5523 HasContextSensitiveKeywords = true;
5524 }
5525 }
5526 // C++ classes can have context-sensitive keywords.
5527 else if (cursor.kind == CXCursor_StructDecl ||
5528 cursor.kind == CXCursor_ClassDecl ||
5529 cursor.kind == CXCursor_ClassTemplate ||
5530 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005531 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 if (D->hasAttr<FinalAttr>())
5533 HasContextSensitiveKeywords = true;
5534 }
5535 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005536
5537 // Don't override a property annotation with its getter/setter method.
5538 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5539 parent.kind == CXCursor_ObjCPropertyDecl)
5540 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005541
5542 if (clang_isPreprocessing(cursor.kind)) {
5543 // Items in the preprocessing record are kept separate from items in
5544 // declarations, so we keep a separate token index.
5545 unsigned SavedTokIdx = TokIdx;
5546 TokIdx = PreprocessingTokIdx;
5547
5548 // Skip tokens up until we catch up to the beginning of the preprocessing
5549 // entry.
5550 while (MoreTokens()) {
5551 const unsigned I = NextToken();
5552 SourceLocation TokLoc = GetTokenLoc(I);
5553 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5554 case RangeBefore:
5555 AdvanceToken();
5556 continue;
5557 case RangeAfter:
5558 case RangeOverlap:
5559 break;
5560 }
5561 break;
5562 }
5563
5564 // Look at all of the tokens within this range.
5565 while (MoreTokens()) {
5566 const unsigned I = NextToken();
5567 SourceLocation TokLoc = GetTokenLoc(I);
5568 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5569 case RangeBefore:
5570 llvm_unreachable("Infeasible");
5571 case RangeAfter:
5572 break;
5573 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005574 // For macro expansions, just note where the beginning of the macro
5575 // expansion occurs.
5576 if (cursor.kind == CXCursor_MacroExpansion) {
5577 if (TokLoc == cursorRange.getBegin())
5578 Cursors[I] = cursor;
5579 AdvanceToken();
5580 break;
5581 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005582 // We may have already annotated macro names inside macro definitions.
5583 if (Cursors[I].kind != CXCursor_MacroExpansion)
5584 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 continue;
5587 }
5588 break;
5589 }
5590
5591 // Save the preprocessing token index; restore the non-preprocessing
5592 // token index.
5593 PreprocessingTokIdx = TokIdx;
5594 TokIdx = SavedTokIdx;
5595 return CXChildVisit_Recurse;
5596 }
5597
5598 if (cursorRange.isInvalid())
5599 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005600
5601 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 const enum CXCursorKind K = clang_getCursorKind(parent);
5604 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005605 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5606 // Attributes are annotated out-of-order, skip tokens until we reach it.
5607 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 ? clang_getNullCursor() : parent;
5609
5610 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5611
5612 // Avoid having the cursor of an expression "overwrite" the annotation of the
5613 // variable declaration that it belongs to.
5614 // This can happen for C++ constructor expressions whose range generally
5615 // include the variable declaration, e.g.:
5616 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005617 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005618 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005619 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 const unsigned I = NextToken();
5621 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5622 E->getLocStart() == D->getLocation() &&
5623 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005624 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 AdvanceToken();
5626 }
5627 }
5628 }
5629
5630 // Before recursing into the children keep some state that we are going
5631 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5632 // extra work after the child nodes are visited.
5633 // Note that we don't call VisitChildren here to avoid traversing statements
5634 // code-recursively which can blow the stack.
5635
5636 PostChildrenInfo Info;
5637 Info.Cursor = cursor;
5638 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005639 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 Info.BeforeChildrenTokenIdx = NextToken();
5641 PostChildrenInfos.push_back(Info);
5642
5643 return CXChildVisit_Recurse;
5644}
5645
5646bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5647 if (PostChildrenInfos.empty())
5648 return false;
5649 const PostChildrenInfo &Info = PostChildrenInfos.back();
5650 if (!clang_equalCursors(Info.Cursor, cursor))
5651 return false;
5652
5653 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5654 const unsigned AfterChildren = NextToken();
5655 SourceRange cursorRange = Info.CursorRange;
5656
5657 // Scan the tokens that are at the end of the cursor, but are not captured
5658 // but the child cursors.
5659 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5660
5661 // Scan the tokens that are at the beginning of the cursor, but are not
5662 // capture by the child cursors.
5663 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5664 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5665 break;
5666
5667 Cursors[I] = cursor;
5668 }
5669
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005670 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5671 // encountered the attribute cursor.
5672 if (clang_isAttribute(cursor.kind))
5673 TokIdx = Info.BeforeReachingCursorIdx;
5674
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 PostChildrenInfos.pop_back();
5676 return false;
5677}
5678
5679static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5680 CXCursor parent,
5681 CXClientData client_data) {
5682 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5683}
5684
5685static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5686 CXClientData client_data) {
5687 return static_cast<AnnotateTokensWorker*>(client_data)->
5688 postVisitChildren(cursor);
5689}
5690
5691namespace {
5692
5693/// \brief Uses the macro expansions in the preprocessing record to find
5694/// and mark tokens that are macro arguments. This info is used by the
5695/// AnnotateTokensWorker.
5696class MarkMacroArgTokensVisitor {
5697 SourceManager &SM;
5698 CXToken *Tokens;
5699 unsigned NumTokens;
5700 unsigned CurIdx;
5701
5702public:
5703 MarkMacroArgTokensVisitor(SourceManager &SM,
5704 CXToken *tokens, unsigned numTokens)
5705 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5706
5707 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5708 if (cursor.kind != CXCursor_MacroExpansion)
5709 return CXChildVisit_Continue;
5710
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005711 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 if (macroRange.getBegin() == macroRange.getEnd())
5713 return CXChildVisit_Continue; // it's not a function macro.
5714
5715 for (; CurIdx < NumTokens; ++CurIdx) {
5716 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5717 macroRange.getBegin()))
5718 break;
5719 }
5720
5721 if (CurIdx == NumTokens)
5722 return CXChildVisit_Break;
5723
5724 for (; CurIdx < NumTokens; ++CurIdx) {
5725 SourceLocation tokLoc = getTokenLoc(CurIdx);
5726 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5727 break;
5728
5729 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5730 }
5731
5732 if (CurIdx == NumTokens)
5733 return CXChildVisit_Break;
5734
5735 return CXChildVisit_Continue;
5736 }
5737
5738private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005739 CXToken &getTok(unsigned Idx) {
5740 assert(Idx < NumTokens);
5741 return Tokens[Idx];
5742 }
5743 const CXToken &getTok(unsigned Idx) const {
5744 assert(Idx < NumTokens);
5745 return Tokens[Idx];
5746 }
5747
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005749 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 }
5751
5752 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5753 // The third field is reserved and currently not used. Use it here
5754 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005755 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 }
5757};
5758
5759} // end anonymous namespace
5760
5761static CXChildVisitResult
5762MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5763 CXClientData client_data) {
5764 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5765 parent);
5766}
5767
5768namespace {
5769 struct clang_annotateTokens_Data {
5770 CXTranslationUnit TU;
5771 ASTUnit *CXXUnit;
5772 CXToken *Tokens;
5773 unsigned NumTokens;
5774 CXCursor *Cursors;
5775 };
5776}
5777
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778/// \brief Used by \c annotatePreprocessorTokens.
5779/// \returns true if lexing was finished, false otherwise.
5780static bool lexNext(Lexer &Lex, Token &Tok,
5781 unsigned &NextIdx, unsigned NumTokens) {
5782 if (NextIdx >= NumTokens)
5783 return true;
5784
5785 ++NextIdx;
5786 Lex.LexFromRawLexer(Tok);
5787 if (Tok.is(tok::eof))
5788 return true;
5789
5790 return false;
5791}
5792
Guy Benyei11169dd2012-12-18 14:30:41 +00005793static void annotatePreprocessorTokens(CXTranslationUnit TU,
5794 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005795 CXCursor *Cursors,
5796 CXToken *Tokens,
5797 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005798 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005799
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005800 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5802 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005803 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005804 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005805 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005806
5807 if (BeginLocInfo.first != EndLocInfo.first)
5808 return;
5809
5810 StringRef Buffer;
5811 bool Invalid = false;
5812 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5813 if (Buffer.empty() || Invalid)
5814 return;
5815
5816 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5817 CXXUnit->getASTContext().getLangOpts(),
5818 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5819 Buffer.end());
5820 Lex.SetCommentRetentionState(true);
5821
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005822 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 // Lex tokens in raw mode until we hit the end of the range, to avoid
5824 // entering #includes or expanding macros.
5825 while (true) {
5826 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005827 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5828 break;
5829 unsigned TokIdx = NextIdx-1;
5830 assert(Tok.getLocation() ==
5831 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005832
5833 reprocess:
5834 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005835 // We have found a preprocessing directive. Annotate the tokens
5836 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 //
5838 // FIXME: Some simple tests here could identify macro definitions and
5839 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005840
5841 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005842 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5843 break;
5844
Craig Topper69186e72014-06-08 08:38:04 +00005845 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005846 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005847 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5848 break;
5849
5850 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005851 IdentifierInfo &II =
5852 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005853 SourceLocation MappedTokLoc =
5854 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5855 MI = getMacroInfo(II, MappedTokLoc, TU);
5856 }
5857 }
5858
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005859 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005861 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5862 finished = true;
5863 break;
5864 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005865 // If we are in a macro definition, check if the token was ever a
5866 // macro name and annotate it if that's the case.
5867 if (MI) {
5868 SourceLocation SaveLoc = Tok.getLocation();
5869 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5870 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5871 Tok.setLocation(SaveLoc);
5872 if (MacroDef)
5873 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5874 Tok.getLocation(), TU);
5875 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005876 } while (!Tok.isAtStartOfLine());
5877
5878 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5879 assert(TokIdx <= LastIdx);
5880 SourceLocation EndLoc =
5881 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5882 CXCursor Cursor =
5883 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5884
5885 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005886 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005887
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005888 if (finished)
5889 break;
5890 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 }
5893}
5894
5895// This gets run a separate thread to avoid stack blowout.
5896static void clang_annotateTokensImpl(void *UserData) {
5897 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5898 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5899 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5900 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5901 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5902
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005903 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5905 setThreadBackgroundPriority();
5906
5907 // Determine the region of interest, which contains all of the tokens.
5908 SourceRange RegionOfInterest;
5909 RegionOfInterest.setBegin(
5910 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5911 RegionOfInterest.setEnd(
5912 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5913 Tokens[NumTokens-1])));
5914
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 // Relex the tokens within the source range to look for preprocessing
5916 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005917 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005918
5919 // If begin location points inside a macro argument, set it to the expansion
5920 // location so we can have the full context when annotating semantically.
5921 {
5922 SourceManager &SM = CXXUnit->getSourceManager();
5923 SourceLocation Loc =
5924 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5925 if (Loc.isMacroID())
5926 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5927 }
5928
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5930 // Search and mark tokens that are macro argument expansions.
5931 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5932 Tokens, NumTokens);
5933 CursorVisitor MacroArgMarker(TU,
5934 MarkMacroArgTokensVisitorDelegate, &Visitor,
5935 /*VisitPreprocessorLast=*/true,
5936 /*VisitIncludedEntities=*/false,
5937 RegionOfInterest);
5938 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5939 }
5940
5941 // Annotate all of the source locations in the region of interest that map to
5942 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005943 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005944
5945 // FIXME: We use a ridiculous stack size here because the data-recursion
5946 // algorithm uses a large stack frame than the non-data recursive version,
5947 // and AnnotationTokensWorker currently transforms the data-recursion
5948 // algorithm back into a traditional recursion by explicitly calling
5949 // VisitChildren(). We will need to remove this explicit recursive call.
5950 W.AnnotateTokens();
5951
5952 // If we ran into any entities that involve context-sensitive keywords,
5953 // take another pass through the tokens to mark them as such.
5954 if (W.hasContextSensitiveKeywords()) {
5955 for (unsigned I = 0; I != NumTokens; ++I) {
5956 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5957 continue;
5958
5959 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5960 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005961 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5963 if (Property->getPropertyAttributesAsWritten() != 0 &&
5964 llvm::StringSwitch<bool>(II->getName())
5965 .Case("readonly", true)
5966 .Case("assign", true)
5967 .Case("unsafe_unretained", true)
5968 .Case("readwrite", true)
5969 .Case("retain", true)
5970 .Case("copy", true)
5971 .Case("nonatomic", true)
5972 .Case("atomic", true)
5973 .Case("getter", true)
5974 .Case("setter", true)
5975 .Case("strong", true)
5976 .Case("weak", true)
5977 .Default(false))
5978 Tokens[I].int_data[0] = CXToken_Keyword;
5979 }
5980 continue;
5981 }
5982
5983 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5984 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5985 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5986 if (llvm::StringSwitch<bool>(II->getName())
5987 .Case("in", true)
5988 .Case("out", true)
5989 .Case("inout", true)
5990 .Case("oneway", true)
5991 .Case("bycopy", true)
5992 .Case("byref", true)
5993 .Default(false))
5994 Tokens[I].int_data[0] = CXToken_Keyword;
5995 continue;
5996 }
5997
5998 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5999 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6000 Tokens[I].int_data[0] = CXToken_Keyword;
6001 continue;
6002 }
6003 }
6004 }
6005}
6006
6007extern "C" {
6008
6009void clang_annotateTokens(CXTranslationUnit TU,
6010 CXToken *Tokens, unsigned NumTokens,
6011 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006012 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006013 LOG_BAD_TU(TU);
6014 return;
6015 }
6016 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006017 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006019 }
6020
6021 LOG_FUNC_SECTION {
6022 *Log << TU << ' ';
6023 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6024 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6025 *Log << clang_getRange(bloc, eloc);
6026 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006027
6028 // Any token we don't specifically annotate will have a NULL cursor.
6029 CXCursor C = clang_getNullCursor();
6030 for (unsigned I = 0; I != NumTokens; ++I)
6031 Cursors[I] = C;
6032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006033 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 if (!CXXUnit)
6035 return;
6036
6037 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6038
6039 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6040 llvm::CrashRecoveryContext CRC;
6041 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6042 GetSafetyThreadStackSize() * 2)) {
6043 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6044 }
6045}
6046
6047} // end: extern "C"
6048
6049//===----------------------------------------------------------------------===//
6050// Operations for querying linkage of a cursor.
6051//===----------------------------------------------------------------------===//
6052
6053extern "C" {
6054CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6055 if (!clang_isDeclaration(cursor.kind))
6056 return CXLinkage_Invalid;
6057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006058 const Decl *D = cxcursor::getCursorDecl(cursor);
6059 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006060 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006061 case NoLinkage:
6062 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 case InternalLinkage: return CXLinkage_Internal;
6064 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6065 case ExternalLinkage: return CXLinkage_External;
6066 };
6067
6068 return CXLinkage_Invalid;
6069}
6070} // end: extern "C"
6071
6072//===----------------------------------------------------------------------===//
6073// Operations for querying language of a cursor.
6074//===----------------------------------------------------------------------===//
6075
6076static CXLanguageKind getDeclLanguage(const Decl *D) {
6077 if (!D)
6078 return CXLanguage_C;
6079
6080 switch (D->getKind()) {
6081 default:
6082 break;
6083 case Decl::ImplicitParam:
6084 case Decl::ObjCAtDefsField:
6085 case Decl::ObjCCategory:
6086 case Decl::ObjCCategoryImpl:
6087 case Decl::ObjCCompatibleAlias:
6088 case Decl::ObjCImplementation:
6089 case Decl::ObjCInterface:
6090 case Decl::ObjCIvar:
6091 case Decl::ObjCMethod:
6092 case Decl::ObjCProperty:
6093 case Decl::ObjCPropertyImpl:
6094 case Decl::ObjCProtocol:
6095 return CXLanguage_ObjC;
6096 case Decl::CXXConstructor:
6097 case Decl::CXXConversion:
6098 case Decl::CXXDestructor:
6099 case Decl::CXXMethod:
6100 case Decl::CXXRecord:
6101 case Decl::ClassTemplate:
6102 case Decl::ClassTemplatePartialSpecialization:
6103 case Decl::ClassTemplateSpecialization:
6104 case Decl::Friend:
6105 case Decl::FriendTemplate:
6106 case Decl::FunctionTemplate:
6107 case Decl::LinkageSpec:
6108 case Decl::Namespace:
6109 case Decl::NamespaceAlias:
6110 case Decl::NonTypeTemplateParm:
6111 case Decl::StaticAssert:
6112 case Decl::TemplateTemplateParm:
6113 case Decl::TemplateTypeParm:
6114 case Decl::UnresolvedUsingTypename:
6115 case Decl::UnresolvedUsingValue:
6116 case Decl::Using:
6117 case Decl::UsingDirective:
6118 case Decl::UsingShadow:
6119 return CXLanguage_CPlusPlus;
6120 }
6121
6122 return CXLanguage_C;
6123}
6124
6125extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006126
6127static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6128 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6129 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006130
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131 switch (D->getAvailability()) {
6132 case AR_Available:
6133 case AR_NotYetIntroduced:
6134 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006135 return getCursorAvailabilityForDecl(
6136 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006137 return CXAvailability_Available;
6138
6139 case AR_Deprecated:
6140 return CXAvailability_Deprecated;
6141
6142 case AR_Unavailable:
6143 return CXAvailability_NotAvailable;
6144 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006145
6146 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006147}
6148
Guy Benyei11169dd2012-12-18 14:30:41 +00006149enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6150 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006151 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6152 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006153
6154 return CXAvailability_Available;
6155}
6156
6157static CXVersion convertVersion(VersionTuple In) {
6158 CXVersion Out = { -1, -1, -1 };
6159 if (In.empty())
6160 return Out;
6161
6162 Out.Major = In.getMajor();
6163
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006164 Optional<unsigned> Minor = In.getMinor();
6165 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006166 Out.Minor = *Minor;
6167 else
6168 return Out;
6169
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006170 Optional<unsigned> Subminor = In.getSubminor();
6171 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 Out.Subminor = *Subminor;
6173
6174 return Out;
6175}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006176
6177static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6178 int *always_deprecated,
6179 CXString *deprecated_message,
6180 int *always_unavailable,
6181 CXString *unavailable_message,
6182 CXPlatformAvailability *availability,
6183 int availability_size) {
6184 bool HadAvailAttr = false;
6185 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006186 for (auto A : D->attrs()) {
6187 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006188 HadAvailAttr = true;
6189 if (always_deprecated)
6190 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006191 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006192 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006193 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006194 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006195 continue;
6196 }
6197
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006198 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006199 HadAvailAttr = true;
6200 if (always_unavailable)
6201 *always_unavailable = 1;
6202 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006203 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006204 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6205 }
6206 continue;
6207 }
6208
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006209 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006210 HadAvailAttr = true;
6211 if (N < availability_size) {
6212 availability[N].Platform
6213 = cxstring::createDup(Avail->getPlatform()->getName());
6214 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6215 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6216 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6217 availability[N].Unavailable = Avail->getUnavailable();
6218 availability[N].Message = cxstring::createDup(Avail->getMessage());
6219 }
6220 ++N;
6221 }
6222 }
6223
6224 if (!HadAvailAttr)
6225 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6226 return getCursorPlatformAvailabilityForDecl(
6227 cast<Decl>(EnumConst->getDeclContext()),
6228 always_deprecated,
6229 deprecated_message,
6230 always_unavailable,
6231 unavailable_message,
6232 availability,
6233 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006234
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006235 return N;
6236}
6237
Guy Benyei11169dd2012-12-18 14:30:41 +00006238int clang_getCursorPlatformAvailability(CXCursor cursor,
6239 int *always_deprecated,
6240 CXString *deprecated_message,
6241 int *always_unavailable,
6242 CXString *unavailable_message,
6243 CXPlatformAvailability *availability,
6244 int availability_size) {
6245 if (always_deprecated)
6246 *always_deprecated = 0;
6247 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006248 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 if (always_unavailable)
6250 *always_unavailable = 0;
6251 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006252 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006253
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 if (!clang_isDeclaration(cursor.kind))
6255 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006256
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006257 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 if (!D)
6259 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006260
6261 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6262 deprecated_message,
6263 always_unavailable,
6264 unavailable_message,
6265 availability,
6266 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006267}
6268
6269void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6270 clang_disposeString(availability->Platform);
6271 clang_disposeString(availability->Message);
6272}
6273
6274CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6275 if (clang_isDeclaration(cursor.kind))
6276 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6277
6278 return CXLanguage_Invalid;
6279}
6280
6281 /// \brief If the given cursor is the "templated" declaration
6282 /// descibing a class or function template, return the class or
6283 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006284static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006285 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006286 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006288 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006289 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6290 return FunTmpl;
6291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006292 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6294 return ClassTmpl;
6295
6296 return D;
6297}
6298
6299CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6300 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006301 if (const Decl *D = getCursorDecl(cursor)) {
6302 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 if (!DC)
6304 return clang_getNullCursor();
6305
6306 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6307 getCursorTU(cursor));
6308 }
6309 }
6310
6311 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006312 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 return MakeCXCursor(D, getCursorTU(cursor));
6314 }
6315
6316 return clang_getNullCursor();
6317}
6318
6319CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6320 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006321 if (const Decl *D = getCursorDecl(cursor)) {
6322 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006323 if (!DC)
6324 return clang_getNullCursor();
6325
6326 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6327 getCursorTU(cursor));
6328 }
6329 }
6330
6331 // FIXME: Note that we can't easily compute the lexical context of a
6332 // statement or expression, so we return nothing.
6333 return clang_getNullCursor();
6334}
6335
6336CXFile clang_getIncludedFile(CXCursor cursor) {
6337 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006338 return nullptr;
6339
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006340 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006341 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006342}
6343
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006344unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6345 if (C.kind != CXCursor_ObjCPropertyDecl)
6346 return CXObjCPropertyAttr_noattr;
6347
6348 unsigned Result = CXObjCPropertyAttr_noattr;
6349 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6350 ObjCPropertyDecl::PropertyAttributeKind Attr =
6351 PD->getPropertyAttributesAsWritten();
6352
6353#define SET_CXOBJCPROP_ATTR(A) \
6354 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6355 Result |= CXObjCPropertyAttr_##A
6356 SET_CXOBJCPROP_ATTR(readonly);
6357 SET_CXOBJCPROP_ATTR(getter);
6358 SET_CXOBJCPROP_ATTR(assign);
6359 SET_CXOBJCPROP_ATTR(readwrite);
6360 SET_CXOBJCPROP_ATTR(retain);
6361 SET_CXOBJCPROP_ATTR(copy);
6362 SET_CXOBJCPROP_ATTR(nonatomic);
6363 SET_CXOBJCPROP_ATTR(setter);
6364 SET_CXOBJCPROP_ATTR(atomic);
6365 SET_CXOBJCPROP_ATTR(weak);
6366 SET_CXOBJCPROP_ATTR(strong);
6367 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6368#undef SET_CXOBJCPROP_ATTR
6369
6370 return Result;
6371}
6372
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006373unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6374 if (!clang_isDeclaration(C.kind))
6375 return CXObjCDeclQualifier_None;
6376
6377 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6378 const Decl *D = getCursorDecl(C);
6379 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6380 QT = MD->getObjCDeclQualifier();
6381 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6382 QT = PD->getObjCDeclQualifier();
6383 if (QT == Decl::OBJC_TQ_None)
6384 return CXObjCDeclQualifier_None;
6385
6386 unsigned Result = CXObjCDeclQualifier_None;
6387 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6388 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6389 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6390 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6391 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6392 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6393
6394 return Result;
6395}
6396
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006397unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6398 if (!clang_isDeclaration(C.kind))
6399 return 0;
6400
6401 const Decl *D = getCursorDecl(C);
6402 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6403 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6404 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6405 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6406
6407 return 0;
6408}
6409
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006410unsigned clang_Cursor_isVariadic(CXCursor C) {
6411 if (!clang_isDeclaration(C.kind))
6412 return 0;
6413
6414 const Decl *D = getCursorDecl(C);
6415 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6416 return FD->isVariadic();
6417 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6418 return MD->isVariadic();
6419
6420 return 0;
6421}
6422
Guy Benyei11169dd2012-12-18 14:30:41 +00006423CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6424 if (!clang_isDeclaration(C.kind))
6425 return clang_getNullRange();
6426
6427 const Decl *D = getCursorDecl(C);
6428 ASTContext &Context = getCursorContext(C);
6429 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6430 if (!RC)
6431 return clang_getNullRange();
6432
6433 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6434}
6435
6436CXString clang_Cursor_getRawCommentText(CXCursor C) {
6437 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006438 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006439
6440 const Decl *D = getCursorDecl(C);
6441 ASTContext &Context = getCursorContext(C);
6442 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6443 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6444 StringRef();
6445
6446 // Don't duplicate the string because RawText points directly into source
6447 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006448 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006449}
6450
6451CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6452 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006453 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006454
6455 const Decl *D = getCursorDecl(C);
6456 const ASTContext &Context = getCursorContext(C);
6457 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6458
6459 if (RC) {
6460 StringRef BriefText = RC->getBriefText(Context);
6461
6462 // Don't duplicate the string because RawComment ensures that this memory
6463 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006464 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 }
6466
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006467 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006468}
6469
Guy Benyei11169dd2012-12-18 14:30:41 +00006470CXModule clang_Cursor_getModule(CXCursor C) {
6471 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006472 if (const ImportDecl *ImportD =
6473 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006474 return ImportD->getImportedModule();
6475 }
6476
Craig Topper69186e72014-06-08 08:38:04 +00006477 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006478}
6479
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006480CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6481 if (isNotUsableTU(TU)) {
6482 LOG_BAD_TU(TU);
6483 return nullptr;
6484 }
6485 if (!File)
6486 return nullptr;
6487 FileEntry *FE = static_cast<FileEntry *>(File);
6488
6489 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6490 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6491 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6492
6493 if (Module *Mod = Header.getModule()) {
6494 if (Header.getRole() != ModuleMap::ExcludedHeader)
6495 return Mod;
6496 }
6497 return nullptr;
6498}
6499
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006500CXFile clang_Module_getASTFile(CXModule CXMod) {
6501 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006502 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006503 Module *Mod = static_cast<Module*>(CXMod);
6504 return const_cast<FileEntry *>(Mod->getASTFile());
6505}
6506
Guy Benyei11169dd2012-12-18 14:30:41 +00006507CXModule clang_Module_getParent(CXModule CXMod) {
6508 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006509 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 Module *Mod = static_cast<Module*>(CXMod);
6511 return Mod->Parent;
6512}
6513
6514CXString clang_Module_getName(CXModule CXMod) {
6515 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006516 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006517 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006518 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006519}
6520
6521CXString clang_Module_getFullName(CXModule CXMod) {
6522 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006523 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006525 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006526}
6527
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006528int clang_Module_isSystem(CXModule CXMod) {
6529 if (!CXMod)
6530 return 0;
6531 Module *Mod = static_cast<Module*>(CXMod);
6532 return Mod->IsSystem;
6533}
6534
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006535unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6536 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006537 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006538 LOG_BAD_TU(TU);
6539 return 0;
6540 }
6541 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006542 return 0;
6543 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006544 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6545 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6546 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006547}
6548
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006549CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6550 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006551 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006552 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006553 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006554 }
6555 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006556 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006557 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006558 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006559
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006560 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6561 if (Index < TopHeaders.size())
6562 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006563
Craig Topper69186e72014-06-08 08:38:04 +00006564 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006565}
6566
6567} // end: extern "C"
6568
6569//===----------------------------------------------------------------------===//
6570// C++ AST instrospection.
6571//===----------------------------------------------------------------------===//
6572
6573extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006574unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6575 if (!clang_isDeclaration(C.kind))
6576 return 0;
6577
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006578 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006579 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006580 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006581 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6582}
6583
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006584unsigned clang_CXXMethod_isConst(CXCursor C) {
6585 if (!clang_isDeclaration(C.kind))
6586 return 0;
6587
6588 const Decl *D = cxcursor::getCursorDecl(C);
6589 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006590 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006591 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6592}
6593
Guy Benyei11169dd2012-12-18 14:30:41 +00006594unsigned clang_CXXMethod_isStatic(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->isStatic()) ? 1 : 0;
6602}
6603
6604unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6605 if (!clang_isDeclaration(C.kind))
6606 return 0;
6607
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006608 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006609 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006610 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006611 return (Method && Method->isVirtual()) ? 1 : 0;
6612}
6613} // end: extern "C"
6614
6615//===----------------------------------------------------------------------===//
6616// Attribute introspection.
6617//===----------------------------------------------------------------------===//
6618
6619extern "C" {
6620CXType clang_getIBOutletCollectionType(CXCursor C) {
6621 if (C.kind != CXCursor_IBOutletCollectionAttr)
6622 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6623
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006624 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6626
6627 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6628}
6629} // end: extern "C"
6630
6631//===----------------------------------------------------------------------===//
6632// Inspecting memory usage.
6633//===----------------------------------------------------------------------===//
6634
6635typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6636
6637static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6638 enum CXTUResourceUsageKind k,
6639 unsigned long amount) {
6640 CXTUResourceUsageEntry entry = { k, amount };
6641 entries.push_back(entry);
6642}
6643
6644extern "C" {
6645
6646const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6647 const char *str = "";
6648 switch (kind) {
6649 case CXTUResourceUsage_AST:
6650 str = "ASTContext: expressions, declarations, and types";
6651 break;
6652 case CXTUResourceUsage_Identifiers:
6653 str = "ASTContext: identifiers";
6654 break;
6655 case CXTUResourceUsage_Selectors:
6656 str = "ASTContext: selectors";
6657 break;
6658 case CXTUResourceUsage_GlobalCompletionResults:
6659 str = "Code completion: cached global results";
6660 break;
6661 case CXTUResourceUsage_SourceManagerContentCache:
6662 str = "SourceManager: content cache allocator";
6663 break;
6664 case CXTUResourceUsage_AST_SideTables:
6665 str = "ASTContext: side tables";
6666 break;
6667 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6668 str = "SourceManager: malloc'ed memory buffers";
6669 break;
6670 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6671 str = "SourceManager: mmap'ed memory buffers";
6672 break;
6673 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6674 str = "ExternalASTSource: malloc'ed memory buffers";
6675 break;
6676 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6677 str = "ExternalASTSource: mmap'ed memory buffers";
6678 break;
6679 case CXTUResourceUsage_Preprocessor:
6680 str = "Preprocessor: malloc'ed memory";
6681 break;
6682 case CXTUResourceUsage_PreprocessingRecord:
6683 str = "Preprocessor: PreprocessingRecord";
6684 break;
6685 case CXTUResourceUsage_SourceManager_DataStructures:
6686 str = "SourceManager: data structures and tables";
6687 break;
6688 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6689 str = "Preprocessor: header search tables";
6690 break;
6691 }
6692 return str;
6693}
6694
6695CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006696 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006697 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006698 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006699 return usage;
6700 }
6701
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006702 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006703 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006704 ASTContext &astContext = astUnit->getASTContext();
6705
6706 // How much memory is used by AST nodes and types?
6707 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6708 (unsigned long) astContext.getASTAllocatedMemory());
6709
6710 // How much memory is used by identifiers?
6711 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6712 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6713
6714 // How much memory is used for selectors?
6715 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6716 (unsigned long) astContext.Selectors.getTotalMemory());
6717
6718 // How much memory is used by ASTContext's side tables?
6719 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6720 (unsigned long) astContext.getSideTableAllocatedMemory());
6721
6722 // How much memory is used for caching global code completion results?
6723 unsigned long completionBytes = 0;
6724 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006725 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006726 completionBytes = completionAllocator->getTotalMemory();
6727 }
6728 createCXTUResourceUsageEntry(*entries,
6729 CXTUResourceUsage_GlobalCompletionResults,
6730 completionBytes);
6731
6732 // How much memory is being used by SourceManager's content cache?
6733 createCXTUResourceUsageEntry(*entries,
6734 CXTUResourceUsage_SourceManagerContentCache,
6735 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6736
6737 // How much memory is being used by the MemoryBuffer's in SourceManager?
6738 const SourceManager::MemoryBufferSizes &srcBufs =
6739 astUnit->getSourceManager().getMemoryBufferSizes();
6740
6741 createCXTUResourceUsageEntry(*entries,
6742 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6743 (unsigned long) srcBufs.malloc_bytes);
6744 createCXTUResourceUsageEntry(*entries,
6745 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6746 (unsigned long) srcBufs.mmap_bytes);
6747 createCXTUResourceUsageEntry(*entries,
6748 CXTUResourceUsage_SourceManager_DataStructures,
6749 (unsigned long) astContext.getSourceManager()
6750 .getDataStructureSizes());
6751
6752 // How much memory is being used by the ExternalASTSource?
6753 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6754 const ExternalASTSource::MemoryBufferSizes &sizes =
6755 esrc->getMemoryBufferSizes();
6756
6757 createCXTUResourceUsageEntry(*entries,
6758 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6759 (unsigned long) sizes.malloc_bytes);
6760 createCXTUResourceUsageEntry(*entries,
6761 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6762 (unsigned long) sizes.mmap_bytes);
6763 }
6764
6765 // How much memory is being used by the Preprocessor?
6766 Preprocessor &pp = astUnit->getPreprocessor();
6767 createCXTUResourceUsageEntry(*entries,
6768 CXTUResourceUsage_Preprocessor,
6769 pp.getTotalMemory());
6770
6771 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6772 createCXTUResourceUsageEntry(*entries,
6773 CXTUResourceUsage_PreprocessingRecord,
6774 pRec->getTotalMemory());
6775 }
6776
6777 createCXTUResourceUsageEntry(*entries,
6778 CXTUResourceUsage_Preprocessor_HeaderSearch,
6779 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006780
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 CXTUResourceUsage usage = { (void*) entries.get(),
6782 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006783 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006784 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 return usage;
6786}
6787
6788void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6789 if (usage.data)
6790 delete (MemUsageEntries*) usage.data;
6791}
6792
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006793CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6794 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006795 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006796 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006797
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006798 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006799 LOG_BAD_TU(TU);
6800 return skipped;
6801 }
6802
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006803 if (!file)
6804 return skipped;
6805
6806 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6807 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6808 if (!ppRec)
6809 return skipped;
6810
6811 ASTContext &Ctx = astUnit->getASTContext();
6812 SourceManager &sm = Ctx.getSourceManager();
6813 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6814 FileID wantedFileID = sm.translateFile(fileEntry);
6815
6816 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6817 std::vector<SourceRange> wantedRanges;
6818 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6819 i != ei; ++i) {
6820 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6821 wantedRanges.push_back(*i);
6822 }
6823
6824 skipped->count = wantedRanges.size();
6825 skipped->ranges = new CXSourceRange[skipped->count];
6826 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6827 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6828
6829 return skipped;
6830}
6831
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006832void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6833 if (ranges) {
6834 delete[] ranges->ranges;
6835 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006836 }
6837}
6838
Guy Benyei11169dd2012-12-18 14:30:41 +00006839} // end extern "C"
6840
6841void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6842 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6843 for (unsigned I = 0; I != Usage.numEntries; ++I)
6844 fprintf(stderr, " %s: %lu\n",
6845 clang_getTUResourceUsageName(Usage.entries[I].kind),
6846 Usage.entries[I].amount);
6847
6848 clang_disposeCXTUResourceUsage(Usage);
6849}
6850
6851//===----------------------------------------------------------------------===//
6852// Misc. utility functions.
6853//===----------------------------------------------------------------------===//
6854
6855/// Default to using an 8 MB stack size on "safety" threads.
6856static unsigned SafetyStackThreadSize = 8 << 20;
6857
6858namespace clang {
6859
6860bool RunSafely(llvm::CrashRecoveryContext &CRC,
6861 void (*Fn)(void*), void *UserData,
6862 unsigned Size) {
6863 if (!Size)
6864 Size = GetSafetyThreadStackSize();
6865 if (Size)
6866 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6867 return CRC.RunSafely(Fn, UserData);
6868}
6869
6870unsigned GetSafetyThreadStackSize() {
6871 return SafetyStackThreadSize;
6872}
6873
6874void SetSafetyThreadStackSize(unsigned Value) {
6875 SafetyStackThreadSize = Value;
6876}
6877
6878}
6879
6880void clang::setThreadBackgroundPriority() {
6881 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6882 return;
6883
Alp Toker1a86ad22014-07-06 06:24:00 +00006884#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006885 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6886#endif
6887}
6888
6889void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6890 if (!Unit)
6891 return;
6892
6893 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6894 DEnd = Unit->stored_diag_end();
6895 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006896 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 CXString Msg = clang_formatDiagnostic(&Diag,
6898 clang_defaultDiagnosticDisplayOptions());
6899 fprintf(stderr, "%s\n", clang_getCString(Msg));
6900 clang_disposeString(Msg);
6901 }
6902#ifdef LLVM_ON_WIN32
6903 // On Windows, force a flush, since there may be multiple copies of
6904 // stderr and stdout in the file system, all with different buffers
6905 // but writing to the same device.
6906 fflush(stderr);
6907#endif
6908}
6909
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006910MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6911 SourceLocation MacroDefLoc,
6912 CXTranslationUnit TU){
6913 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006914 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006915 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006917
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006918 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006919 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006920 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006921 if (MD) {
6922 for (MacroDirective::DefInfo
6923 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6924 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6925 return Def.getMacroInfo();
6926 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006927 }
6928
Craig Topper69186e72014-06-08 08:38:04 +00006929 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006930}
6931
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006932const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6933 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006934 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006936 const IdentifierInfo *II = MacroDef->getName();
6937 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006938 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006939
6940 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6941}
6942
6943MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6944 const Token &Tok,
6945 CXTranslationUnit TU) {
6946 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006947 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006948 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006949 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006950
6951 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006953 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6954 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006955 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006956
6957 // Check that the token is inside the definition and not its argument list.
6958 SourceManager &SM = Unit->getSourceManager();
6959 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006960 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006961 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006962 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006963
6964 Preprocessor &PP = Unit->getPreprocessor();
6965 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6966 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006967 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006968
Alp Toker2d57cea2014-05-17 04:53:25 +00006969 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006970 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006971 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006972
6973 // Check that the identifier is not one of the macro arguments.
6974 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006975 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006976
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006977 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6978 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006979 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006980
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006981 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006982}
6983
6984MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6985 SourceLocation Loc,
6986 CXTranslationUnit TU) {
6987 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006988 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006989
6990 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006991 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006992 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006993 Preprocessor &PP = Unit->getPreprocessor();
6994 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006995 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006996 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6997 Token Tok;
6998 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000
7001 return checkForMacroInMacroDefinition(MI, Tok, TU);
7002}
7003
Guy Benyei11169dd2012-12-18 14:30:41 +00007004extern "C" {
7005
7006CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007007 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007008}
7009
7010} // end: extern "C"
7011
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007012Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7013 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007014 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007015 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007016 if (Unit->isMainFileAST())
7017 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007018 return *this;
7019 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007020 } else {
7021 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007022 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007023 return *this;
7024}
7025
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007026Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7027 *this << FE->getName();
7028 return *this;
7029}
7030
7031Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7032 CXString cursorName = clang_getCursorDisplayName(cursor);
7033 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7034 clang_disposeString(cursorName);
7035 return *this;
7036}
7037
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007038Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7039 CXFile File;
7040 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007041 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007042 CXString FileName = clang_getFileName(File);
7043 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7044 clang_disposeString(FileName);
7045 return *this;
7046}
7047
7048Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7049 CXSourceLocation BLoc = clang_getRangeStart(range);
7050 CXSourceLocation ELoc = clang_getRangeEnd(range);
7051
7052 CXFile BFile;
7053 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007054 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007055
7056 CXFile EFile;
7057 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007058 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007059
7060 CXString BFileName = clang_getFileName(BFile);
7061 if (BFile == EFile) {
7062 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7063 BLine, BColumn, ELine, EColumn);
7064 } else {
7065 CXString EFileName = clang_getFileName(EFile);
7066 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7067 BLine, BColumn)
7068 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7069 ELine, EColumn);
7070 clang_disposeString(EFileName);
7071 }
7072 clang_disposeString(BFileName);
7073 return *this;
7074}
7075
7076Logger &cxindex::Logger::operator<<(CXString Str) {
7077 *this << clang_getCString(Str);
7078 return *this;
7079}
7080
7081Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7082 LogOS << Fmt;
7083 return *this;
7084}
7085
Chandler Carruth37ad2582014-06-27 15:14:39 +00007086static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7087
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007088cxindex::Logger::~Logger() {
7089 LogOS.flush();
7090
Chandler Carruth37ad2582014-06-27 15:14:39 +00007091 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007092
7093 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7094
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007095 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007096 OS << "[libclang:" << Name << ':';
7097
Alp Toker1a86ad22014-07-06 06:24:00 +00007098#ifdef USE_DARWIN_THREADS
7099 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007100 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7101 OS << tid << ':';
7102#endif
7103
7104 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7105 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7106 OS << Msg.str() << '\n';
7107
7108 if (Trace) {
7109 llvm::sys::PrintStackTrace(stderr);
7110 OS << "--------------------------------------------------\n";
7111 }
7112}