blob: c124b1ab0de67e96f57ff9b846ac7bad4f489afd [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001787 case Stmt::OMPCriticalDirectiveClass:
1788 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001861 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001862 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001863 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001864 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001865 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001866 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001867 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001868 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001869 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001870 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001871 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001872 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001873 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001874 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001875 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876
Guy Benyei11169dd2012-12-18 14:30:41 +00001877private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1880 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1882 void AddStmt(const Stmt *S);
1883 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001886 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888} // end anonyous namespace
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 // 'S' should always be non-null, since it comes from the
1892 // statement we are visiting.
1893 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1894}
1895
1896void
1897EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1898 if (Qualifier)
1899 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1900}
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (S)
1904 WL.push_back(StmtVisit(S, Parent));
1905}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (D)
1908 WL.push_back(DeclVisit(D, Parent, isFirst));
1909}
1910void EnqueueVisitor::
1911 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1912 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001914}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001915void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 if (D)
1917 WL.push_back(MemberRefVisit(D, L, Parent));
1918}
1919void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1920 if (TI)
1921 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1922 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 AddStmt(*Child);
1927 }
1928 if (size == WL.size())
1929 return;
1930 // Now reverse the entries we just added. This will match the DFS
1931 // ordering performed by the worklist.
1932 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1933 std::reverse(I, E);
1934}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935namespace {
1936class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1937 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001938 /// \brief Process clauses with list of variables.
1939 template <typename T>
1940 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941public:
1942 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1943#define OPENMP_CLAUSE(Name, Class) \
1944 void Visit##Class(const Class *C);
1945#include "clang/Basic/OpenMPKinds.def"
1946};
1947
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001948void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1949 Visitor->AddStmt(C->getCondition());
1950}
1951
Alexey Bataev3778b602014-07-17 07:32:53 +00001952void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev568a8332014-03-06 06:15:19 +00001956void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1957 Visitor->AddStmt(C->getNumThreads());
1958}
1959
Alexey Bataev62c87d22014-03-21 04:51:18 +00001960void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1961 Visitor->AddStmt(C->getSafelen());
1962}
1963
Alexander Musman8bd31e62014-05-27 15:12:19 +00001964void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1965 Visitor->AddStmt(C->getNumForLoops());
1966}
1967
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001969
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001970void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1971
Alexey Bataev56dafe82014-06-20 07:16:17 +00001972void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1973 Visitor->AddStmt(C->getChunkSize());
1974}
1975
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001976void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1977
Alexey Bataev236070f2014-06-20 11:19:47 +00001978void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1979
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001980void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1981
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001982void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1983
Alexey Bataev756c1962013-09-24 03:17:45 +00001984template<typename T>
1985void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001986 for (const auto *I : Node->varlists())
1987 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001988}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001989
1990void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001991 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001992}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001993void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1994 const OMPFirstprivateClause *C) {
1995 VisitOMPClauseList(C);
1996}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001997void OMPClauseEnqueue::VisitOMPLastprivateClause(
1998 const OMPLastprivateClause *C) {
1999 VisitOMPClauseList(C);
2000}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002001void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002002 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002003}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002004void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2005 VisitOMPClauseList(C);
2006}
Alexander Musman8dba6642014-04-22 13:09:42 +00002007void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2008 VisitOMPClauseList(C);
2009 Visitor->AddStmt(C->getStep());
2010}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002011void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2012 VisitOMPClauseList(C);
2013 Visitor->AddStmt(C->getAlignment());
2014}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002015void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2016 VisitOMPClauseList(C);
2017}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002018void
2019OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexey Bataev6125da92014-07-21 11:26:11 +00002022void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2023 VisitOMPClauseList(C);
2024}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002025}
Alexey Bataev756c1962013-09-24 03:17:45 +00002026
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002027void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2028 unsigned size = WL.size();
2029 OMPClauseEnqueue Visitor(this);
2030 Visitor.Visit(S);
2031 if (size == WL.size())
2032 return;
2033 // Now reverse the entries we just added. This will match the DFS
2034 // ordering performed by the worklist.
2035 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2036 std::reverse(I, E);
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 AddDecl(B->getBlockDecl());
2043}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 AddTypeLoc(E->getTypeSourceInfo());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2049 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 E = S->body_rend(); I != E; ++I) {
2051 AddStmt(*I);
2052 }
2053}
2054void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 AddStmt(S->getSubStmt());
2057 AddDeclarationNameInfo(S);
2058 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2059 AddNestedNameSpecifierLoc(QualifierLoc);
2060}
2061
2062void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2065 AddDeclarationNameInfo(E);
2066 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2067 AddNestedNameSpecifierLoc(QualifierLoc);
2068 if (!E->isImplicitAccess())
2069 AddStmt(E->getBase());
2070}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 // Enqueue the initializer , if any.
2073 AddStmt(E->getInitializer());
2074 // Enqueue the array size, if any.
2075 AddStmt(E->getArraySize());
2076 // Enqueue the allocated type.
2077 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2078 // Enqueue the placement arguments.
2079 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2080 AddStmt(E->getPlacementArg(I-1));
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2084 AddStmt(CE->getArg(I-1));
2085 AddStmt(CE->getCallee());
2086 AddStmt(CE->getArg(0));
2087}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2089 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 // Visit the name of the type being destroyed.
2091 AddTypeLoc(E->getDestroyedTypeInfo());
2092 // Visit the scope type that looks disturbingly like the nested-name-specifier
2093 // but isn't.
2094 AddTypeLoc(E->getScopeTypeInfo());
2095 // Visit the nested-name-specifier.
2096 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2097 AddNestedNameSpecifierLoc(QualifierLoc);
2098 // Visit base expression.
2099 AddStmt(E->getBase());
2100}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2102 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 AddTypeLoc(E->getTypeSourceInfo());
2104}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2106 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 EnqueueChildren(E);
2108 AddTypeLoc(E->getTypeSourceInfo());
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 EnqueueChildren(E);
2112 if (E->isTypeOperand())
2113 AddTypeLoc(E->getTypeOperandSourceInfo());
2114}
2115
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2117 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 EnqueueChildren(E);
2119 AddTypeLoc(E->getTypeSourceInfo());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 EnqueueChildren(E);
2123 if (E->isTypeOperand())
2124 AddTypeLoc(E->getTypeOperandSourceInfo());
2125}
2126
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 EnqueueChildren(S);
2129 AddDecl(S->getExceptionDecl());
2130}
2131
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 if (DR->hasExplicitTemplateArgs()) {
2134 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2135 }
2136 WL.push_back(DeclRefExprParts(DR, Parent));
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2139 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2141 AddDeclarationNameInfo(E);
2142 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 unsigned size = WL.size();
2146 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002147 for (const auto *D : S->decls()) {
2148 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 isFirst = false;
2150 }
2151 if (size == WL.size())
2152 return;
2153 // Now reverse the entries we just added. This will match the DFS
2154 // ordering performed by the worklist.
2155 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2156 std::reverse(I, E);
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 D = E->designators_rbegin(), DEnd = E->designators_rend();
2162 D != DEnd; ++D) {
2163 if (D->isFieldDesignator()) {
2164 if (FieldDecl *Field = D->getField())
2165 AddMemberRef(Field, D->getFieldLoc());
2166 continue;
2167 }
2168 if (D->isArrayDesignator()) {
2169 AddStmt(E->getArrayIndex(*D));
2170 continue;
2171 }
2172 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2173 AddStmt(E->getArrayRangeEnd(*D));
2174 AddStmt(E->getArrayRangeStart(*D));
2175 }
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 EnqueueChildren(E);
2179 AddTypeLoc(E->getTypeInfoAsWritten());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddStmt(FS->getBody());
2183 AddStmt(FS->getInc());
2184 AddStmt(FS->getCond());
2185 AddDecl(FS->getConditionVariable());
2186 AddStmt(FS->getInit());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(If->getElse());
2193 AddStmt(If->getThen());
2194 AddStmt(If->getCond());
2195 AddDecl(If->getConditionVariable());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 // We care about the syntactic form of the initializer list, only.
2199 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2200 IE = Syntactic;
2201 EnqueueChildren(IE);
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 WL.push_back(MemberExprParts(M, Parent));
2205
2206 // If the base of the member access expression is an implicit 'this', don't
2207 // visit it.
2208 // FIXME: If we ever want to show these implicit accesses, this will be
2209 // unfortunate. However, clang_getCursor() relies on this behavior.
2210 if (!M->isImplicitAccess())
2211 AddStmt(M->getBase());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 AddTypeLoc(E->getEncodedTypeSourceInfo());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 EnqueueChildren(M);
2218 AddTypeLoc(M->getClassReceiverTypeInfo());
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 // Visit the components of the offsetof expression.
2222 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2223 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2224 const OffsetOfNode &Node = E->getComponent(I-1);
2225 switch (Node.getKind()) {
2226 case OffsetOfNode::Array:
2227 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2228 break;
2229 case OffsetOfNode::Field:
2230 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2231 break;
2232 case OffsetOfNode::Identifier:
2233 case OffsetOfNode::Base:
2234 continue;
2235 }
2236 }
2237 // Visit the type into which we're computing the offset.
2238 AddTypeLoc(E->getTypeSourceInfo());
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2242 WL.push_back(OverloadExprParts(E, Parent));
2243}
2244void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 EnqueueChildren(E);
2247 if (E->isArgumentType())
2248 AddTypeLoc(E->getArgumentTypeInfo());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(S);
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 AddStmt(S->getBody());
2255 AddStmt(S->getCond());
2256 AddDecl(S->getConditionVariable());
2257}
2258
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 AddStmt(W->getBody());
2261 AddStmt(W->getCond());
2262 AddDecl(W->getConditionVariable());
2263}
2264
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 for (unsigned I = E->getNumArgs(); I > 0; --I)
2267 AddTypeLoc(E->getArg(I-1));
2268}
2269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddTypeLoc(E->getQueriedTypeSourceInfo());
2272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueChildren(E);
2276}
2277
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 VisitOverloadExpr(U);
2280 if (!U->isImplicitAccess())
2281 AddStmt(U->getBase());
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 AddStmt(E->getSubExpr());
2285 AddTypeLoc(E->getWrittenTypeInfo());
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 WL.push_back(SizeOfPackExprParts(E, Parent));
2289}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 // If the opaque value has a source expression, just transparently
2292 // visit that. This is useful for (e.g.) pseudo-object expressions.
2293 if (Expr *SourceExpr = E->getSourceExpr())
2294 return Visit(SourceExpr);
2295}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 AddStmt(E->getBody());
2298 WL.push_back(LambdaExprParts(E, Parent));
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 // Treat the expression like its syntactic form.
2302 Visit(E->getSyntacticForm());
2303}
2304
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002305void EnqueueVisitor::VisitOMPExecutableDirective(
2306 const OMPExecutableDirective *D) {
2307 EnqueueChildren(D);
2308 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2309 E = D->clauses().end();
2310 I != E; ++I)
2311 EnqueueChildren(*I);
2312}
2313
2314void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2315 VisitOMPExecutableDirective(D);
2316}
2317
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002318void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2319 VisitOMPExecutableDirective(D);
2320}
2321
Alexey Bataevf29276e2014-06-18 04:14:57 +00002322void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2323 VisitOMPExecutableDirective(D);
2324}
2325
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002326void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2327 VisitOMPExecutableDirective(D);
2328}
2329
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002330void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2331 VisitOMPExecutableDirective(D);
2332}
2333
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002334void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexander Musman80c22892014-07-17 08:54:58 +00002338void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2339 VisitOMPExecutableDirective(D);
2340}
2341
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002342void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2343 VisitOMPExecutableDirective(D);
2344 AddDeclarationNameInfo(D);
2345}
2346
Alexey Bataev4acb8592014-07-07 13:01:15 +00002347void
2348EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2349 VisitOMPExecutableDirective(D);
2350}
2351
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002352void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2353 const OMPParallelSectionsDirective *D) {
2354 VisitOMPExecutableDirective(D);
2355}
2356
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002357void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2358 VisitOMPExecutableDirective(D);
2359}
2360
Alexey Bataev68446b72014-07-18 07:47:19 +00002361void
2362EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002366void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2367 VisitOMPExecutableDirective(D);
2368}
2369
Alexey Bataev2df347a2014-07-18 10:17:07 +00002370void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2371 VisitOMPExecutableDirective(D);
2372}
2373
Alexey Bataev6125da92014-07-21 11:26:11 +00002374void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2375 VisitOMPExecutableDirective(D);
2376}
2377
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002378void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2379 VisitOMPExecutableDirective(D);
2380}
2381
Alexey Bataev0162e452014-07-22 10:10:35 +00002382void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2383 VisitOMPExecutableDirective(D);
2384}
2385
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2388}
2389
2390bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2391 if (RegionOfInterest.isValid()) {
2392 SourceRange Range = getRawCursorExtent(C);
2393 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2394 return false;
2395 }
2396 return true;
2397}
2398
2399bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2400 while (!WL.empty()) {
2401 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002402 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002403
2404 // Set the Parent field, then back to its old value once we're done.
2405 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2406
2407 switch (LI.getKind()) {
2408 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 if (!D)
2411 continue;
2412
2413 // For now, perform default visitation for Decls.
2414 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2415 cast<DeclVisit>(&LI)->isFirst())))
2416 return true;
2417
2418 continue;
2419 }
2420 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2421 const ASTTemplateArgumentListInfo *ArgList =
2422 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2423 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2424 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2425 Arg != ArgEnd; ++Arg) {
2426 if (VisitTemplateArgumentLoc(*Arg))
2427 return true;
2428 }
2429 continue;
2430 }
2431 case VisitorJob::TypeLocVisitKind: {
2432 // Perform default visitation for TypeLocs.
2433 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2434 return true;
2435 continue;
2436 }
2437 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 if (LabelStmt *stmt = LS->getStmt()) {
2440 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2441 TU))) {
2442 return true;
2443 }
2444 }
2445 continue;
2446 }
2447
2448 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2449 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2450 if (VisitNestedNameSpecifierLoc(V->get()))
2451 return true;
2452 continue;
2453 }
2454
2455 case VisitorJob::DeclarationNameInfoVisitKind: {
2456 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2457 ->get()))
2458 return true;
2459 continue;
2460 }
2461 case VisitorJob::MemberRefVisitKind: {
2462 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2463 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2464 return true;
2465 continue;
2466 }
2467 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 if (!S)
2470 continue;
2471
2472 // Update the current cursor.
2473 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2474 if (!IsInRegionOfInterest(Cursor))
2475 continue;
2476 switch (Visitor(Cursor, Parent, ClientData)) {
2477 case CXChildVisit_Break: return true;
2478 case CXChildVisit_Continue: break;
2479 case CXChildVisit_Recurse:
2480 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002481 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 EnqueueWorkList(WL, S);
2483 break;
2484 }
2485 continue;
2486 }
2487 case VisitorJob::MemberExprPartsKind: {
2488 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002489 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002490
2491 // Visit the nested-name-specifier
2492 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2493 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2494 return true;
2495
2496 // Visit the declaration name.
2497 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2498 return true;
2499
2500 // Visit the explicitly-specified template arguments, if any.
2501 if (M->hasExplicitTemplateArgs()) {
2502 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2503 *ArgEnd = Arg + M->getNumTemplateArgs();
2504 Arg != ArgEnd; ++Arg) {
2505 if (VisitTemplateArgumentLoc(*Arg))
2506 return true;
2507 }
2508 }
2509 continue;
2510 }
2511 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002512 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 // Visit nested-name-specifier, if present.
2514 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2515 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2516 return true;
2517 // Visit declaration name.
2518 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2519 return true;
2520 continue;
2521 }
2522 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 // Visit the nested-name-specifier.
2525 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2526 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2527 return true;
2528 // Visit the declaration name.
2529 if (VisitDeclarationNameInfo(O->getNameInfo()))
2530 return true;
2531 // Visit the overloaded declaration reference.
2532 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2533 return true;
2534 continue;
2535 }
2536 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 NamedDecl *Pack = E->getPack();
2539 if (isa<TemplateTypeParmDecl>(Pack)) {
2540 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2541 E->getPackLoc(), TU)))
2542 return true;
2543
2544 continue;
2545 }
2546
2547 if (isa<TemplateTemplateParmDecl>(Pack)) {
2548 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2549 E->getPackLoc(), TU)))
2550 return true;
2551
2552 continue;
2553 }
2554
2555 // Non-type template parameter packs and function parameter packs are
2556 // treated like DeclRefExpr cursors.
2557 continue;
2558 }
2559
2560 case VisitorJob::LambdaExprPartsKind: {
2561 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002562 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002563 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2564 CEnd = E->explicit_capture_end();
2565 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002566 // FIXME: Lambda init-captures.
2567 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002568 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002569
Guy Benyei11169dd2012-12-18 14:30:41 +00002570 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2571 C->getLocation(),
2572 TU)))
2573 return true;
2574 }
2575
2576 // Visit parameters and return type, if present.
2577 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2578 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2579 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2580 // Visit the whole type.
2581 if (Visit(TL))
2582 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002583 } else if (FunctionProtoTypeLoc Proto =
2584 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002585 if (E->hasExplicitParameters()) {
2586 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002587 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2588 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 return true;
2590 } else {
2591 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002592 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002593 return true;
2594 }
2595 }
2596 }
2597 break;
2598 }
2599
2600 case VisitorJob::PostChildrenVisitKind:
2601 if (PostChildrenVisitor(Parent, ClientData))
2602 return true;
2603 break;
2604 }
2605 }
2606 return false;
2607}
2608
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002609bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002610 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 if (!WorkListFreeList.empty()) {
2612 WL = WorkListFreeList.back();
2613 WL->clear();
2614 WorkListFreeList.pop_back();
2615 }
2616 else {
2617 WL = new VisitorWorkList();
2618 WorkListCache.push_back(WL);
2619 }
2620 EnqueueWorkList(*WL, S);
2621 bool result = RunVisitorWorkList(*WL);
2622 WorkListFreeList.push_back(WL);
2623 return result;
2624}
2625
2626namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002627typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002628RefNamePieces
2629buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2630 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2631 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002632 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2633 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2634 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2635
2636 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2637
2638 RefNamePieces Pieces;
2639
2640 if (WantQualifier && QLoc.isValid())
2641 Pieces.push_back(QLoc);
2642
2643 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2644 Pieces.push_back(NI.getLoc());
2645
2646 if (WantTemplateArgs && TemplateArgs)
2647 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2648 TemplateArgs->RAngleLoc));
2649
2650 if (Kind == DeclarationName::CXXOperatorName) {
2651 Pieces.push_back(SourceLocation::getFromRawEncoding(
2652 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2653 Pieces.push_back(SourceLocation::getFromRawEncoding(
2654 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2655 }
2656
2657 if (WantSinglePiece) {
2658 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2659 Pieces.clear();
2660 Pieces.push_back(R);
2661 }
2662
2663 return Pieces;
2664}
2665}
2666
2667//===----------------------------------------------------------------------===//
2668// Misc. API hooks.
2669//===----------------------------------------------------------------------===//
2670
Chad Rosier05c71aa2013-03-27 18:28:23 +00002671static void fatal_error_handler(void *user_data, const std::string& reason,
2672 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 // Write the result out to stderr avoiding errs() because raw_ostreams can
2674 // call report_fatal_error.
2675 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2676 ::abort();
2677}
2678
Chandler Carruth66660742014-06-27 16:37:27 +00002679namespace {
2680struct RegisterFatalErrorHandler {
2681 RegisterFatalErrorHandler() {
2682 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2683 }
2684};
2685}
2686
2687static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2688
Guy Benyei11169dd2012-12-18 14:30:41 +00002689extern "C" {
2690CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2691 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 // We use crash recovery to make some of our APIs more reliable, implicitly
2693 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002694 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2695 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002696
Chandler Carruth66660742014-06-27 16:37:27 +00002697 // Look through the managed static to trigger construction of the managed
2698 // static which registers our fatal error handler. This ensures it is only
2699 // registered once.
2700 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002701
2702 CIndexer *CIdxr = new CIndexer();
2703 if (excludeDeclarationsFromPCH)
2704 CIdxr->setOnlyLocalDecls();
2705 if (displayDiagnostics)
2706 CIdxr->setDisplayDiagnostics();
2707
2708 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2709 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2710 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2711 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2712 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2713 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2714
2715 return CIdxr;
2716}
2717
2718void clang_disposeIndex(CXIndex CIdx) {
2719 if (CIdx)
2720 delete static_cast<CIndexer *>(CIdx);
2721}
2722
2723void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2724 if (CIdx)
2725 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2726}
2727
2728unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2729 if (CIdx)
2730 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2731 return 0;
2732}
2733
2734void clang_toggleCrashRecovery(unsigned isEnabled) {
2735 if (isEnabled)
2736 llvm::CrashRecoveryContext::Enable();
2737 else
2738 llvm::CrashRecoveryContext::Disable();
2739}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002740
Guy Benyei11169dd2012-12-18 14:30:41 +00002741CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2742 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002743 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002744 enum CXErrorCode Result =
2745 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002746 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002747 assert((TU && Result == CXError_Success) ||
2748 (!TU && Result != CXError_Success));
2749 return TU;
2750}
2751
2752enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2753 const char *ast_filename,
2754 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002755 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002756 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002757
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 if (!CIdx || !ast_filename || !out_TU)
2759 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002760
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002761 LOG_FUNC_SECTION {
2762 *Log << ast_filename;
2763 }
2764
Guy Benyei11169dd2012-12-18 14:30:41 +00002765 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2766 FileSystemOptions FileSystemOpts;
2767
2768 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002769 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002770 CXXIdx->getOnlyLocalDecls(), None,
2771 /*CaptureDiagnostics=*/true,
2772 /*AllowPCHWithCompilerErrors=*/true,
2773 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002774 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2775 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002776}
2777
2778unsigned clang_defaultEditingTranslationUnitOptions() {
2779 return CXTranslationUnit_PrecompiledPreamble |
2780 CXTranslationUnit_CacheCompletionResults;
2781}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002782
Guy Benyei11169dd2012-12-18 14:30:41 +00002783CXTranslationUnit
2784clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2785 const char *source_filename,
2786 int num_command_line_args,
2787 const char * const *command_line_args,
2788 unsigned num_unsaved_files,
2789 struct CXUnsavedFile *unsaved_files) {
2790 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2791 return clang_parseTranslationUnit(CIdx, source_filename,
2792 command_line_args, num_command_line_args,
2793 unsaved_files, num_unsaved_files,
2794 Options);
2795}
2796
2797struct ParseTranslationUnitInfo {
2798 CXIndex CIdx;
2799 const char *source_filename;
2800 const char *const *command_line_args;
2801 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002802 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002803 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002805 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806};
2807static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002808 const ParseTranslationUnitInfo *PTUI =
2809 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002810 CXIndex CIdx = PTUI->CIdx;
2811 const char *source_filename = PTUI->source_filename;
2812 const char * const *command_line_args = PTUI->command_line_args;
2813 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002816
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002817 // Set up the initial return values.
2818 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002819 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002820
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002821 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002822 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002825 }
2826
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2828
2829 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2830 setThreadBackgroundPriority();
2831
2832 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2833 // FIXME: Add a flag for modules.
2834 TranslationUnitKind TUKind
2835 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002836 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 = options & CXTranslationUnit_CacheCompletionResults;
2838 bool IncludeBriefCommentsInCodeCompletion
2839 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2840 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2841 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2842
2843 // Configure the diagnostics.
2844 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002845 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002846
2847 // Recover resources if we crash before exiting this function.
2848 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2849 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002850 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002851
Ahmed Charlesb8984322014-03-07 20:03:18 +00002852 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2853 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002854
2855 // Recover resources if we crash before exiting this function.
2856 llvm::CrashRecoveryContextCleanupRegistrar<
2857 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2858
Alp Toker9d85b182014-07-07 01:23:14 +00002859 for (auto &UF : PTUI->unsaved_files) {
2860 llvm::MemoryBuffer *MB =
2861 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2862 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 }
2864
Ahmed Charlesb8984322014-03-07 20:03:18 +00002865 std::unique_ptr<std::vector<const char *>> Args(
2866 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002867
2868 // Recover resources if we crash before exiting this method.
2869 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2870 ArgsCleanup(Args.get());
2871
2872 // Since the Clang C library is primarily used by batch tools dealing with
2873 // (often very broken) source code, where spell-checking can have a
2874 // significant negative impact on performance (particularly when
2875 // precompiled headers are involved), we disable it by default.
2876 // Only do this if we haven't found a spell-checking-related argument.
2877 bool FoundSpellCheckingArgument = false;
2878 for (int I = 0; I != num_command_line_args; ++I) {
2879 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2880 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2881 FoundSpellCheckingArgument = true;
2882 break;
2883 }
2884 }
2885 if (!FoundSpellCheckingArgument)
2886 Args->push_back("-fno-spell-checking");
2887
2888 Args->insert(Args->end(), command_line_args,
2889 command_line_args + num_command_line_args);
2890
2891 // The 'source_filename' argument is optional. If the caller does not
2892 // specify it then it is assumed that the source file is specified
2893 // in the actual argument list.
2894 // Put the source file after command_line_args otherwise if '-x' flag is
2895 // present it will be unused.
2896 if (source_filename)
2897 Args->push_back(source_filename);
2898
2899 // Do we need the detailed preprocessing record?
2900 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2901 Args->push_back("-Xclang");
2902 Args->push_back("-detailed-preprocessing-record");
2903 }
2904
2905 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002906 std::unique_ptr<ASTUnit> ErrUnit;
2907 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002908 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002909 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2910 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2911 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2912 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2913 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2914 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002915
2916 if (NumErrors != Diags->getClient()->getNumErrors()) {
2917 // Make sure to check that 'Unit' is non-NULL.
2918 if (CXXIdx->getDisplayDiagnostics())
2919 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2920 }
2921
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002922 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2923 PTUI->result = CXError_ASTReadError;
2924 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002925 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002926 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2927 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002928}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002929
2930CXTranslationUnit
2931clang_parseTranslationUnit(CXIndex CIdx,
2932 const char *source_filename,
2933 const char *const *command_line_args,
2934 int num_command_line_args,
2935 struct CXUnsavedFile *unsaved_files,
2936 unsigned num_unsaved_files,
2937 unsigned options) {
2938 CXTranslationUnit TU;
2939 enum CXErrorCode Result = clang_parseTranslationUnit2(
2940 CIdx, source_filename, command_line_args, num_command_line_args,
2941 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002942 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002943 assert((TU && Result == CXError_Success) ||
2944 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002945 return TU;
2946}
2947
2948enum CXErrorCode clang_parseTranslationUnit2(
2949 CXIndex CIdx,
2950 const char *source_filename,
2951 const char *const *command_line_args,
2952 int num_command_line_args,
2953 struct CXUnsavedFile *unsaved_files,
2954 unsigned num_unsaved_files,
2955 unsigned options,
2956 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002957 LOG_FUNC_SECTION {
2958 *Log << source_filename << ": ";
2959 for (int i = 0; i != num_command_line_args; ++i)
2960 *Log << command_line_args[i] << " ";
2961 }
2962
Alp Toker9d85b182014-07-07 01:23:14 +00002963 if (num_unsaved_files && !unsaved_files)
2964 return CXError_InvalidArguments;
2965
Alp Toker5c532982014-07-07 22:42:03 +00002966 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002967 ParseTranslationUnitInfo PTUI = {
2968 CIdx,
2969 source_filename,
2970 command_line_args,
2971 num_command_line_args,
2972 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2973 options,
2974 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002975 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002976 llvm::CrashRecoveryContext CRC;
2977
2978 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2979 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2980 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2981 fprintf(stderr, " 'command_line_args' : [");
2982 for (int i = 0; i != num_command_line_args; ++i) {
2983 if (i)
2984 fprintf(stderr, ", ");
2985 fprintf(stderr, "'%s'", command_line_args[i]);
2986 }
2987 fprintf(stderr, "],\n");
2988 fprintf(stderr, " 'unsaved_files' : [");
2989 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2990 if (i)
2991 fprintf(stderr, ", ");
2992 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2993 unsaved_files[i].Length);
2994 }
2995 fprintf(stderr, "],\n");
2996 fprintf(stderr, " 'options' : %d,\n", options);
2997 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998
2999 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003000 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003001 if (CXTranslationUnit *TU = PTUI.out_TU)
3002 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 }
Alp Toker5c532982014-07-07 22:42:03 +00003004
3005 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003006}
3007
3008unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3009 return CXSaveTranslationUnit_None;
3010}
3011
3012namespace {
3013
3014struct SaveTranslationUnitInfo {
3015 CXTranslationUnit TU;
3016 const char *FileName;
3017 unsigned options;
3018 CXSaveError result;
3019};
3020
3021}
3022
3023static void clang_saveTranslationUnit_Impl(void *UserData) {
3024 SaveTranslationUnitInfo *STUI =
3025 static_cast<SaveTranslationUnitInfo*>(UserData);
3026
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003027 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3029 setThreadBackgroundPriority();
3030
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003031 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3033}
3034
3035int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3036 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003037 LOG_FUNC_SECTION {
3038 *Log << TU << ' ' << FileName;
3039 }
3040
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003041 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003042 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003044 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003046 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3048 if (!CXXUnit->hasSema())
3049 return CXSaveError_InvalidTU;
3050
3051 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3052
3053 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3054 getenv("LIBCLANG_NOTHREADS")) {
3055 clang_saveTranslationUnit_Impl(&STUI);
3056
3057 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3058 PrintLibclangResourceUsage(TU);
3059
3060 return STUI.result;
3061 }
3062
3063 // We have an AST that has invalid nodes due to compiler errors.
3064 // Use a crash recovery thread for protection.
3065
3066 llvm::CrashRecoveryContext CRC;
3067
3068 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3069 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3070 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3071 fprintf(stderr, " 'options' : %d,\n", options);
3072 fprintf(stderr, "}\n");
3073
3074 return CXSaveError_Unknown;
3075
3076 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3077 PrintLibclangResourceUsage(TU);
3078 }
3079
3080 return STUI.result;
3081}
3082
3083void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3084 if (CTUnit) {
3085 // If the translation unit has been marked as unsafe to free, just discard
3086 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003087 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3088 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 return;
3090
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003091 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003092 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3094 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003095 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 delete CTUnit;
3097 }
3098}
3099
3100unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3101 return CXReparse_None;
3102}
3103
3104struct ReparseTranslationUnitInfo {
3105 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003106 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003108 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003109};
3110
3111static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003112 const ReparseTranslationUnitInfo *RTUI =
3113 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003115 unsigned options = RTUI->options;
3116 (void) options;
3117
3118 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003119 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121 RTUI->result = CXError_InvalidArguments;
3122 return;
3123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003124
3125 // Reset the associated diagnostics.
3126 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003127 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003128
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003129 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3131 setThreadBackgroundPriority();
3132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003135
3136 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3137 new std::vector<ASTUnit::RemappedFile>());
3138
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 // Recover resources if we crash before exiting this function.
3140 llvm::CrashRecoveryContextCleanupRegistrar<
3141 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003142
3143 for (auto &UF : RTUI->unsaved_files) {
3144 llvm::MemoryBuffer *MB =
3145 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3146 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003148
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003149 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150 RTUI->result = CXError_Success;
3151 else if (isASTReadError(CXXUnit))
3152 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003153}
3154
3155int clang_reparseTranslationUnit(CXTranslationUnit TU,
3156 unsigned num_unsaved_files,
3157 struct CXUnsavedFile *unsaved_files,
3158 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003159 LOG_FUNC_SECTION {
3160 *Log << TU;
3161 }
3162
Alp Toker9d85b182014-07-07 01:23:14 +00003163 if (num_unsaved_files && !unsaved_files)
3164 return CXError_InvalidArguments;
3165
Alp Toker5c532982014-07-07 22:42:03 +00003166 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003167 ReparseTranslationUnitInfo RTUI = {
3168 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003169 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003170
3171 if (getenv("LIBCLANG_NOTHREADS")) {
3172 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003173 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 }
3175
3176 llvm::CrashRecoveryContext CRC;
3177
3178 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3179 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003180 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003181 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3183 PrintLibclangResourceUsage(TU);
3184
Alp Toker5c532982014-07-07 22:42:03 +00003185 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003186}
3187
3188
3189CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003190 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003191 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003192 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003193 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003194
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003195 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003196 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003197}
3198
3199CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003200 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003201 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003202 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003203 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003204
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003205 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3207}
3208
3209} // end: extern "C"
3210
3211//===----------------------------------------------------------------------===//
3212// CXFile Operations.
3213//===----------------------------------------------------------------------===//
3214
3215extern "C" {
3216CXString clang_getFileName(CXFile SFile) {
3217 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003218 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003219
3220 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003221 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003222}
3223
3224time_t clang_getFileTime(CXFile SFile) {
3225 if (!SFile)
3226 return 0;
3227
3228 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3229 return FEnt->getModificationTime();
3230}
3231
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003232CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003233 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003234 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003235 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003236 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003237
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003238 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003239
3240 FileManager &FMgr = CXXUnit->getFileManager();
3241 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3242}
3243
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3245 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003246 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003247 LOG_BAD_TU(TU);
3248 return 0;
3249 }
3250
3251 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return 0;
3253
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003254 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 FileEntry *FEnt = static_cast<FileEntry *>(file);
3256 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3257 .isFileMultipleIncludeGuarded(FEnt);
3258}
3259
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003260int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3261 if (!file || !outID)
3262 return 1;
3263
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003264 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003265 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3266 outID->data[0] = ID.getDevice();
3267 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003268 outID->data[2] = FEnt->getModificationTime();
3269 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003270}
3271
Guy Benyei11169dd2012-12-18 14:30:41 +00003272} // end: extern "C"
3273
3274//===----------------------------------------------------------------------===//
3275// CXCursor Operations.
3276//===----------------------------------------------------------------------===//
3277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003278static const Decl *getDeclFromExpr(const Stmt *E) {
3279 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 return getDeclFromExpr(CE->getSubExpr());
3281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 if (PRE->isExplicitProperty())
3290 return PRE->getExplicitProperty();
3291 // It could be messaging both getter and setter as in:
3292 // ++myobj.myprop;
3293 // in which case prefer to associate the setter since it is less obvious
3294 // from inspecting the source that the setter is going to get called.
3295 if (PRE->isMessagingSetter())
3296 return PRE->getImplicitPropertySetter();
3297 return PRE->getImplicitPropertyGetter();
3298 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003299 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003301 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 if (Expr *Src = OVE->getSourceExpr())
3303 return getDeclFromExpr(Src);
3304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003305 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003307 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 if (!CE->isElidable())
3309 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 return OME->getMethodDecl();
3312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3317 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3320 isa<ParmVarDecl>(SizeOfPack->getPack()))
3321 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003322
3323 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003324}
3325
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003326static SourceLocation getLocationFromExpr(const Expr *E) {
3327 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 return getLocationFromExpr(CE->getSubExpr());
3329
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003330 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003332 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003334 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003336 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003338 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003340 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return PropRef->getLocation();
3342
3343 return E->getLocStart();
3344}
3345
3346extern "C" {
3347
3348unsigned clang_visitChildren(CXCursor parent,
3349 CXCursorVisitor visitor,
3350 CXClientData client_data) {
3351 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3352 /*VisitPreprocessorLast=*/false);
3353 return CursorVis.VisitChildren(parent);
3354}
3355
3356#ifndef __has_feature
3357#define __has_feature(x) 0
3358#endif
3359#if __has_feature(blocks)
3360typedef enum CXChildVisitResult
3361 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3362
3363static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3364 CXClientData client_data) {
3365 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3366 return block(cursor, parent);
3367}
3368#else
3369// If we are compiled with a compiler that doesn't have native blocks support,
3370// define and call the block manually, so the
3371typedef struct _CXChildVisitResult
3372{
3373 void *isa;
3374 int flags;
3375 int reserved;
3376 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3377 CXCursor);
3378} *CXCursorVisitorBlock;
3379
3380static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3381 CXClientData client_data) {
3382 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3383 return block->invoke(block, cursor, parent);
3384}
3385#endif
3386
3387
3388unsigned clang_visitChildrenWithBlock(CXCursor parent,
3389 CXCursorVisitorBlock block) {
3390 return clang_visitChildren(parent, visitWithBlock, block);
3391}
3392
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003395 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003396
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003397 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003399 if (const ObjCPropertyImplDecl *PropImpl =
3400 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003402 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003406 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003407
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003408 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 }
3410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003412 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003414 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3416 // and returns different names. NamedDecl returns the class name and
3417 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
3420 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003421 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003422
3423 SmallString<1024> S;
3424 llvm::raw_svector_ostream os(S);
3425 ND->printName(os);
3426
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003427 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003428}
3429
3430CXString clang_getCursorSpelling(CXCursor C) {
3431 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003432 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 if (clang_isReference(C.kind)) {
3435 switch (C.kind) {
3436 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003437 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 }
3440 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003441 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003442 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 }
3444 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003445 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003447 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003450 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003451 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 }
3453 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003454 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 assert(Type && "Missing type decl");
3456
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003457 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 getAsString());
3459 }
3460 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003461 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 assert(Template && "Missing template decl");
3463
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003464 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466
3467 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003468 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 assert(NS && "Missing namespace decl");
3470
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 }
3473
3474 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003475 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 assert(Field && "Missing member decl");
3477
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003478 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480
3481 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003482 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 assert(Label && "Missing label");
3484
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003485 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 }
3487
3488 case CXCursor_OverloadedDeclRef: {
3489 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3491 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003493 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003496 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 OverloadedTemplateStorage *Ovl
3498 = Storage.get<OverloadedTemplateStorage*>();
3499 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003500 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003501 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
3503
3504 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003505 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 assert(Var && "Missing variable decl");
3507
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 }
3510
3511 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003512 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514 }
3515
3516 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003517 const Expr *E = getCursorExpr(C);
3518
3519 if (C.kind == CXCursor_ObjCStringLiteral ||
3520 C.kind == CXCursor_StringLiteral) {
3521 const StringLiteral *SLit;
3522 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3523 SLit = OSL->getString();
3524 } else {
3525 SLit = cast<StringLiteral>(E);
3526 }
3527 SmallString<256> Buf;
3528 llvm::raw_svector_ostream OS(Buf);
3529 SLit->outputString(OS);
3530 return cxstring::createDup(OS.str());
3531 }
3532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 if (D)
3535 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003536 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 }
3538
3539 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003540 const Stmt *S = getCursorStmt(C);
3541 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003542 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003543
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003544 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546
3547 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 ->getNameStart());
3550
3551 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 ->getNameStart());
3554
3555 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003556 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003557
3558 if (clang_isDeclaration(C.kind))
3559 return getDeclSpelling(getCursorDecl(C));
3560
3561 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003562 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003563 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 }
3565
3566 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003567 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003568 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 }
3570
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003571 if (C.kind == CXCursor_PackedAttr) {
3572 return cxstring::createRef("packed");
3573 }
3574
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003575 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003576}
3577
3578CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3579 unsigned pieceIndex,
3580 unsigned options) {
3581 if (clang_Cursor_isNull(C))
3582 return clang_getNullRange();
3583
3584 ASTContext &Ctx = getCursorContext(C);
3585
3586 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003587 const Stmt *S = getCursorStmt(C);
3588 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 if (pieceIndex > 0)
3590 return clang_getNullRange();
3591 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3592 }
3593
3594 return clang_getNullRange();
3595 }
3596
3597 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003598 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3600 if (pieceIndex >= ME->getNumSelectorLocs())
3601 return clang_getNullRange();
3602 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3603 }
3604 }
3605
3606 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3607 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003608 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3610 if (pieceIndex >= MD->getNumSelectorLocs())
3611 return clang_getNullRange();
3612 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3613 }
3614 }
3615
3616 if (C.kind == CXCursor_ObjCCategoryDecl ||
3617 C.kind == CXCursor_ObjCCategoryImplDecl) {
3618 if (pieceIndex > 0)
3619 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003620 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3622 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003623 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3625 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3626 }
3627
3628 if (C.kind == CXCursor_ModuleImportDecl) {
3629 if (pieceIndex > 0)
3630 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003631 if (const ImportDecl *ImportD =
3632 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3634 if (!Locs.empty())
3635 return cxloc::translateSourceRange(Ctx,
3636 SourceRange(Locs.front(), Locs.back()));
3637 }
3638 return clang_getNullRange();
3639 }
3640
3641 // FIXME: A CXCursor_InclusionDirective should give the location of the
3642 // filename, but we don't keep track of this.
3643
3644 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3645 // but we don't keep track of this.
3646
3647 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3648 // but we don't keep track of this.
3649
3650 // Default handling, give the location of the cursor.
3651
3652 if (pieceIndex > 0)
3653 return clang_getNullRange();
3654
3655 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3656 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3657 return cxloc::translateSourceRange(Ctx, Loc);
3658}
3659
3660CXString clang_getCursorDisplayName(CXCursor C) {
3661 if (!clang_isDeclaration(C.kind))
3662 return clang_getCursorSpelling(C);
3663
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003664 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003666 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003667
3668 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003669 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 D = FunTmpl->getTemplatedDecl();
3671
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 SmallString<64> Str;
3674 llvm::raw_svector_ostream OS(Str);
3675 OS << *Function;
3676 if (Function->getPrimaryTemplate())
3677 OS << "<>";
3678 OS << "(";
3679 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3680 if (I)
3681 OS << ", ";
3682 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3683 }
3684
3685 if (Function->isVariadic()) {
3686 if (Function->getNumParams())
3687 OS << ", ";
3688 OS << "...";
3689 }
3690 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003694 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 SmallString<64> Str;
3696 llvm::raw_svector_ostream OS(Str);
3697 OS << *ClassTemplate;
3698 OS << "<";
3699 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3700 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3701 if (I)
3702 OS << ", ";
3703
3704 NamedDecl *Param = Params->getParam(I);
3705 if (Param->getIdentifier()) {
3706 OS << Param->getIdentifier()->getName();
3707 continue;
3708 }
3709
3710 // There is no parameter name, which makes this tricky. Try to come up
3711 // with something useful that isn't too long.
3712 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3713 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3714 else if (NonTypeTemplateParmDecl *NTTP
3715 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3716 OS << NTTP->getType().getAsString(Policy);
3717 else
3718 OS << "template<...> class";
3719 }
3720
3721 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003722 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 }
3724
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003725 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3727 // If the type was explicitly written, use that.
3728 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003729 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003730
Benjamin Kramer9170e912013-02-22 15:46:01 +00003731 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 llvm::raw_svector_ostream OS(Str);
3733 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003734 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 ClassSpec->getTemplateArgs().data(),
3736 ClassSpec->getTemplateArgs().size(),
3737 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003738 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 }
3740
3741 return clang_getCursorSpelling(C);
3742}
3743
3744CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3745 switch (Kind) {
3746 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003874 case CXCursor_ObjCSelfExpr:
3875 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003964 case CXCursor_SEHLeaveStmt:
3965 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003994 case CXCursor_PackedAttr:
3995 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003996 case CXCursor_PureAttr:
3997 return cxstring::createRef("attribute(pure)");
3998 case CXCursor_ConstAttr:
3999 return cxstring::createRef("attribute(const)");
4000 case CXCursor_NoDuplicateAttr:
4001 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004002 case CXCursor_CUDAConstantAttr:
4003 return cxstring::createRef("attribute(constant)");
4004 case CXCursor_CUDADeviceAttr:
4005 return cxstring::createRef("attribute(device)");
4006 case CXCursor_CUDAGlobalAttr:
4007 return cxstring::createRef("attribute(global)");
4008 case CXCursor_CUDAHostAttr:
4009 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004058 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004059 return cxstring::createRef("OMPParallelDirective");
4060 case CXCursor_OMPSimdDirective:
4061 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004062 case CXCursor_OMPForDirective:
4063 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004064 case CXCursor_OMPSectionsDirective:
4065 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004066 case CXCursor_OMPSectionDirective:
4067 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004068 case CXCursor_OMPSingleDirective:
4069 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004070 case CXCursor_OMPMasterDirective:
4071 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004072 case CXCursor_OMPCriticalDirective:
4073 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004074 case CXCursor_OMPParallelForDirective:
4075 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004076 case CXCursor_OMPParallelSectionsDirective:
4077 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004078 case CXCursor_OMPTaskDirective:
4079 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004080 case CXCursor_OMPTaskyieldDirective:
4081 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004082 case CXCursor_OMPBarrierDirective:
4083 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004084 case CXCursor_OMPTaskwaitDirective:
4085 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004086 case CXCursor_OMPFlushDirective:
4087 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004088 case CXCursor_OMPOrderedDirective:
4089 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004090 case CXCursor_OMPAtomicDirective:
4091 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 }
4093
4094 llvm_unreachable("Unhandled CXCursorKind");
4095}
4096
4097struct GetCursorData {
4098 SourceLocation TokenBeginLoc;
4099 bool PointsAtMacroArgExpansion;
4100 bool VisitedObjCPropertyImplDecl;
4101 SourceLocation VisitedDeclaratorDeclStartLoc;
4102 CXCursor &BestCursor;
4103
4104 GetCursorData(SourceManager &SM,
4105 SourceLocation tokenBegin, CXCursor &outputCursor)
4106 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4107 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4108 VisitedObjCPropertyImplDecl = false;
4109 }
4110};
4111
4112static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4113 CXCursor parent,
4114 CXClientData client_data) {
4115 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4116 CXCursor *BestCursor = &Data->BestCursor;
4117
4118 // If we point inside a macro argument we should provide info of what the
4119 // token is so use the actual cursor, don't replace it with a macro expansion
4120 // cursor.
4121 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4122 return CXChildVisit_Recurse;
4123
4124 if (clang_isDeclaration(cursor.kind)) {
4125 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004126 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4128 if (MD->isImplicit())
4129 return CXChildVisit_Break;
4130
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004131 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4133 // Check that when we have multiple @class references in the same line,
4134 // that later ones do not override the previous ones.
4135 // If we have:
4136 // @class Foo, Bar;
4137 // source ranges for both start at '@', so 'Bar' will end up overriding
4138 // 'Foo' even though the cursor location was at 'Foo'.
4139 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4140 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004141 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4143 if (PrevID != ID &&
4144 !PrevID->isThisDeclarationADefinition() &&
4145 !ID->isThisDeclarationADefinition())
4146 return CXChildVisit_Break;
4147 }
4148
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004149 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4151 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4152 // Check that when we have multiple declarators in the same line,
4153 // that later ones do not override the previous ones.
4154 // If we have:
4155 // int Foo, Bar;
4156 // source ranges for both start at 'int', so 'Bar' will end up overriding
4157 // 'Foo' even though the cursor location was at 'Foo'.
4158 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4159 return CXChildVisit_Break;
4160 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004162 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4164 (void)PropImp;
4165 // Check that when we have multiple @synthesize in the same line,
4166 // that later ones do not override the previous ones.
4167 // If we have:
4168 // @synthesize Foo, Bar;
4169 // source ranges for both start at '@', so 'Bar' will end up overriding
4170 // 'Foo' even though the cursor location was at 'Foo'.
4171 if (Data->VisitedObjCPropertyImplDecl)
4172 return CXChildVisit_Break;
4173 Data->VisitedObjCPropertyImplDecl = true;
4174 }
4175 }
4176
4177 if (clang_isExpression(cursor.kind) &&
4178 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004179 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 // Avoid having the cursor of an expression replace the declaration cursor
4181 // when the expression source range overlaps the declaration range.
4182 // This can happen for C++ constructor expressions whose range generally
4183 // include the variable declaration, e.g.:
4184 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4185 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4186 D->getLocation() == Data->TokenBeginLoc)
4187 return CXChildVisit_Break;
4188 }
4189 }
4190
4191 // If our current best cursor is the construction of a temporary object,
4192 // don't replace that cursor with a type reference, because we want
4193 // clang_getCursor() to point at the constructor.
4194 if (clang_isExpression(BestCursor->kind) &&
4195 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4196 cursor.kind == CXCursor_TypeRef) {
4197 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4198 // as having the actual point on the type reference.
4199 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4200 return CXChildVisit_Recurse;
4201 }
4202
4203 *BestCursor = cursor;
4204 return CXChildVisit_Recurse;
4205}
4206
4207CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004208 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004209 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004211 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004212
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004213 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4215
4216 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4217 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4218
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004219 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 CXFile SearchFile;
4221 unsigned SearchLine, SearchColumn;
4222 CXFile ResultFile;
4223 unsigned ResultLine, ResultColumn;
4224 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4225 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4226 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004227
4228 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4229 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004230 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004231 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 SearchFileName = clang_getFileName(SearchFile);
4233 ResultFileName = clang_getFileName(ResultFile);
4234 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4235 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004236 *Log << llvm::format("(%s:%d:%d) = %s",
4237 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4238 clang_getCString(KindSpelling))
4239 << llvm::format("(%s:%d:%d):%s%s",
4240 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4241 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 clang_disposeString(SearchFileName);
4243 clang_disposeString(ResultFileName);
4244 clang_disposeString(KindSpelling);
4245 clang_disposeString(USR);
4246
4247 CXCursor Definition = clang_getCursorDefinition(Result);
4248 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4249 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4250 CXString DefinitionKindSpelling
4251 = clang_getCursorKindSpelling(Definition.kind);
4252 CXFile DefinitionFile;
4253 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004254 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004255 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004257 *Log << llvm::format(" -> %s(%s:%d:%d)",
4258 clang_getCString(DefinitionKindSpelling),
4259 clang_getCString(DefinitionFileName),
4260 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 clang_disposeString(DefinitionFileName);
4262 clang_disposeString(DefinitionKindSpelling);
4263 }
4264 }
4265
4266 return Result;
4267}
4268
4269CXCursor clang_getNullCursor(void) {
4270 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4271}
4272
4273unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004274 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4275 // can't set consistently. For example, when visiting a DeclStmt we will set
4276 // it but we don't set it on the result of clang_getCursorDefinition for
4277 // a reference of the same declaration.
4278 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4279 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4280 // to provide that kind of info.
4281 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004282 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004283 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004284 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004285
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 return X == Y;
4287}
4288
4289unsigned clang_hashCursor(CXCursor C) {
4290 unsigned Index = 0;
4291 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4292 Index = 1;
4293
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004294 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 std::make_pair(C.kind, C.data[Index]));
4296}
4297
4298unsigned clang_isInvalid(enum CXCursorKind K) {
4299 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4300}
4301
4302unsigned clang_isDeclaration(enum CXCursorKind K) {
4303 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4304 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4305}
4306
4307unsigned clang_isReference(enum CXCursorKind K) {
4308 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4309}
4310
4311unsigned clang_isExpression(enum CXCursorKind K) {
4312 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4313}
4314
4315unsigned clang_isStatement(enum CXCursorKind K) {
4316 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4317}
4318
4319unsigned clang_isAttribute(enum CXCursorKind K) {
4320 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4321}
4322
4323unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4324 return K == CXCursor_TranslationUnit;
4325}
4326
4327unsigned clang_isPreprocessing(enum CXCursorKind K) {
4328 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4329}
4330
4331unsigned clang_isUnexposed(enum CXCursorKind K) {
4332 switch (K) {
4333 case CXCursor_UnexposedDecl:
4334 case CXCursor_UnexposedExpr:
4335 case CXCursor_UnexposedStmt:
4336 case CXCursor_UnexposedAttr:
4337 return true;
4338 default:
4339 return false;
4340 }
4341}
4342
4343CXCursorKind clang_getCursorKind(CXCursor C) {
4344 return C.kind;
4345}
4346
4347CXSourceLocation clang_getCursorLocation(CXCursor C) {
4348 if (clang_isReference(C.kind)) {
4349 switch (C.kind) {
4350 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004351 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 = getCursorObjCSuperClassRef(C);
4353 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4354 }
4355
4356 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004357 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 = getCursorObjCProtocolRef(C);
4359 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4360 }
4361
4362 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004363 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 = getCursorObjCClassRef(C);
4365 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4366 }
4367
4368 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004369 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4371 }
4372
4373 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004374 std::pair<const TemplateDecl *, SourceLocation> P =
4375 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4377 }
4378
4379 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004380 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4382 }
4383
4384 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004385 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4387 }
4388
4389 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004390 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4392 }
4393
4394 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004395 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 if (!BaseSpec)
4397 return clang_getNullLocation();
4398
4399 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4400 return cxloc::translateSourceLocation(getCursorContext(C),
4401 TSInfo->getTypeLoc().getBeginLoc());
4402
4403 return cxloc::translateSourceLocation(getCursorContext(C),
4404 BaseSpec->getLocStart());
4405 }
4406
4407 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004408 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4410 }
4411
4412 case CXCursor_OverloadedDeclRef:
4413 return cxloc::translateSourceLocation(getCursorContext(C),
4414 getCursorOverloadedDeclRef(C).second);
4415
4416 default:
4417 // FIXME: Need a way to enumerate all non-reference cases.
4418 llvm_unreachable("Missed a reference kind");
4419 }
4420 }
4421
4422 if (clang_isExpression(C.kind))
4423 return cxloc::translateSourceLocation(getCursorContext(C),
4424 getLocationFromExpr(getCursorExpr(C)));
4425
4426 if (clang_isStatement(C.kind))
4427 return cxloc::translateSourceLocation(getCursorContext(C),
4428 getCursorStmt(C)->getLocStart());
4429
4430 if (C.kind == CXCursor_PreprocessingDirective) {
4431 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4432 return cxloc::translateSourceLocation(getCursorContext(C), L);
4433 }
4434
4435 if (C.kind == CXCursor_MacroExpansion) {
4436 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004437 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 return cxloc::translateSourceLocation(getCursorContext(C), L);
4439 }
4440
4441 if (C.kind == CXCursor_MacroDefinition) {
4442 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4443 return cxloc::translateSourceLocation(getCursorContext(C), L);
4444 }
4445
4446 if (C.kind == CXCursor_InclusionDirective) {
4447 SourceLocation L
4448 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4449 return cxloc::translateSourceLocation(getCursorContext(C), L);
4450 }
4451
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004452 if (clang_isAttribute(C.kind)) {
4453 SourceLocation L
4454 = cxcursor::getCursorAttr(C)->getLocation();
4455 return cxloc::translateSourceLocation(getCursorContext(C), L);
4456 }
4457
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (!clang_isDeclaration(C.kind))
4459 return clang_getNullLocation();
4460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004461 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 if (!D)
4463 return clang_getNullLocation();
4464
4465 SourceLocation Loc = D->getLocation();
4466 // FIXME: Multiple variables declared in a single declaration
4467 // currently lack the information needed to correctly determine their
4468 // ranges when accounting for the type-specifier. We use context
4469 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4470 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004471 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 if (!cxcursor::isFirstInDeclGroup(C))
4473 Loc = VD->getLocation();
4474 }
4475
4476 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004477 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 Loc = MD->getSelectorStartLoc();
4479
4480 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4481}
4482
4483} // end extern "C"
4484
4485CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4486 assert(TU);
4487
4488 // Guard against an invalid SourceLocation, or we may assert in one
4489 // of the following calls.
4490 if (SLoc.isInvalid())
4491 return clang_getNullCursor();
4492
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004493 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004494
4495 // Translate the given source location to make it point at the beginning of
4496 // the token under the cursor.
4497 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4498 CXXUnit->getASTContext().getLangOpts());
4499
4500 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4501 if (SLoc.isValid()) {
4502 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4503 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4504 /*VisitPreprocessorLast=*/true,
4505 /*VisitIncludedEntities=*/false,
4506 SourceLocation(SLoc));
4507 CursorVis.visitFileRegion();
4508 }
4509
4510 return Result;
4511}
4512
4513static SourceRange getRawCursorExtent(CXCursor C) {
4514 if (clang_isReference(C.kind)) {
4515 switch (C.kind) {
4516 case CXCursor_ObjCSuperClassRef:
4517 return getCursorObjCSuperClassRef(C).second;
4518
4519 case CXCursor_ObjCProtocolRef:
4520 return getCursorObjCProtocolRef(C).second;
4521
4522 case CXCursor_ObjCClassRef:
4523 return getCursorObjCClassRef(C).second;
4524
4525 case CXCursor_TypeRef:
4526 return getCursorTypeRef(C).second;
4527
4528 case CXCursor_TemplateRef:
4529 return getCursorTemplateRef(C).second;
4530
4531 case CXCursor_NamespaceRef:
4532 return getCursorNamespaceRef(C).second;
4533
4534 case CXCursor_MemberRef:
4535 return getCursorMemberRef(C).second;
4536
4537 case CXCursor_CXXBaseSpecifier:
4538 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4539
4540 case CXCursor_LabelRef:
4541 return getCursorLabelRef(C).second;
4542
4543 case CXCursor_OverloadedDeclRef:
4544 return getCursorOverloadedDeclRef(C).second;
4545
4546 case CXCursor_VariableRef:
4547 return getCursorVariableRef(C).second;
4548
4549 default:
4550 // FIXME: Need a way to enumerate all non-reference cases.
4551 llvm_unreachable("Missed a reference kind");
4552 }
4553 }
4554
4555 if (clang_isExpression(C.kind))
4556 return getCursorExpr(C)->getSourceRange();
4557
4558 if (clang_isStatement(C.kind))
4559 return getCursorStmt(C)->getSourceRange();
4560
4561 if (clang_isAttribute(C.kind))
4562 return getCursorAttr(C)->getRange();
4563
4564 if (C.kind == CXCursor_PreprocessingDirective)
4565 return cxcursor::getCursorPreprocessingDirective(C);
4566
4567 if (C.kind == CXCursor_MacroExpansion) {
4568 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004569 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 return TU->mapRangeFromPreamble(Range);
4571 }
4572
4573 if (C.kind == CXCursor_MacroDefinition) {
4574 ASTUnit *TU = getCursorASTUnit(C);
4575 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4576 return TU->mapRangeFromPreamble(Range);
4577 }
4578
4579 if (C.kind == CXCursor_InclusionDirective) {
4580 ASTUnit *TU = getCursorASTUnit(C);
4581 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4582 return TU->mapRangeFromPreamble(Range);
4583 }
4584
4585 if (C.kind == CXCursor_TranslationUnit) {
4586 ASTUnit *TU = getCursorASTUnit(C);
4587 FileID MainID = TU->getSourceManager().getMainFileID();
4588 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4589 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4590 return SourceRange(Start, End);
4591 }
4592
4593 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 if (!D)
4596 return SourceRange();
4597
4598 SourceRange R = D->getSourceRange();
4599 // FIXME: Multiple variables declared in a single declaration
4600 // currently lack the information needed to correctly determine their
4601 // ranges when accounting for the type-specifier. We use context
4602 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4603 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004604 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 if (!cxcursor::isFirstInDeclGroup(C))
4606 R.setBegin(VD->getLocation());
4607 }
4608 return R;
4609 }
4610 return SourceRange();
4611}
4612
4613/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4614/// the decl-specifier-seq for declarations.
4615static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4616 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004617 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 if (!D)
4619 return SourceRange();
4620
4621 SourceRange R = D->getSourceRange();
4622
4623 // Adjust the start of the location for declarations preceded by
4624 // declaration specifiers.
4625 SourceLocation StartLoc;
4626 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4627 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4628 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004629 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4631 StartLoc = TI->getTypeLoc().getLocStart();
4632 }
4633
4634 if (StartLoc.isValid() && R.getBegin().isValid() &&
4635 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4636 R.setBegin(StartLoc);
4637
4638 // FIXME: Multiple variables declared in a single declaration
4639 // currently lack the information needed to correctly determine their
4640 // ranges when accounting for the type-specifier. We use context
4641 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4642 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004643 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 if (!cxcursor::isFirstInDeclGroup(C))
4645 R.setBegin(VD->getLocation());
4646 }
4647
4648 return R;
4649 }
4650
4651 return getRawCursorExtent(C);
4652}
4653
4654extern "C" {
4655
4656CXSourceRange clang_getCursorExtent(CXCursor C) {
4657 SourceRange R = getRawCursorExtent(C);
4658 if (R.isInvalid())
4659 return clang_getNullRange();
4660
4661 return cxloc::translateSourceRange(getCursorContext(C), R);
4662}
4663
4664CXCursor clang_getCursorReferenced(CXCursor C) {
4665 if (clang_isInvalid(C.kind))
4666 return clang_getNullCursor();
4667
4668 CXTranslationUnit tu = getCursorTU(C);
4669 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004670 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 if (!D)
4672 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004673 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004675 if (const ObjCPropertyImplDecl *PropImpl =
4676 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4678 return MakeCXCursor(Property, tu);
4679
4680 return C;
4681 }
4682
4683 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004684 const Expr *E = getCursorExpr(C);
4685 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 if (D) {
4687 CXCursor declCursor = MakeCXCursor(D, tu);
4688 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4689 declCursor);
4690 return declCursor;
4691 }
4692
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004693 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 return MakeCursorOverloadedDeclRef(Ovl, tu);
4695
4696 return clang_getNullCursor();
4697 }
4698
4699 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004700 const Stmt *S = getCursorStmt(C);
4701 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 if (LabelDecl *label = Goto->getLabel())
4703 if (LabelStmt *labelS = label->getStmt())
4704 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4705
4706 return clang_getNullCursor();
4707 }
4708
4709 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004710 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 return MakeMacroDefinitionCursor(Def, tu);
4712 }
4713
4714 if (!clang_isReference(C.kind))
4715 return clang_getNullCursor();
4716
4717 switch (C.kind) {
4718 case CXCursor_ObjCSuperClassRef:
4719 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4720
4721 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004722 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4723 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 return MakeCXCursor(Def, tu);
4725
4726 return MakeCXCursor(Prot, tu);
4727 }
4728
4729 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004730 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4731 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 return MakeCXCursor(Def, tu);
4733
4734 return MakeCXCursor(Class, tu);
4735 }
4736
4737 case CXCursor_TypeRef:
4738 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4739
4740 case CXCursor_TemplateRef:
4741 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4742
4743 case CXCursor_NamespaceRef:
4744 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4745
4746 case CXCursor_MemberRef:
4747 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4748
4749 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004750 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4752 tu ));
4753 }
4754
4755 case CXCursor_LabelRef:
4756 // FIXME: We end up faking the "parent" declaration here because we
4757 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004758 return MakeCXCursor(getCursorLabelRef(C).first,
4759 cxtu::getASTUnit(tu)->getASTContext()
4760 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 tu);
4762
4763 case CXCursor_OverloadedDeclRef:
4764 return C;
4765
4766 case CXCursor_VariableRef:
4767 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4768
4769 default:
4770 // We would prefer to enumerate all non-reference cursor kinds here.
4771 llvm_unreachable("Unhandled reference cursor kind");
4772 }
4773}
4774
4775CXCursor clang_getCursorDefinition(CXCursor C) {
4776 if (clang_isInvalid(C.kind))
4777 return clang_getNullCursor();
4778
4779 CXTranslationUnit TU = getCursorTU(C);
4780
4781 bool WasReference = false;
4782 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4783 C = clang_getCursorReferenced(C);
4784 WasReference = true;
4785 }
4786
4787 if (C.kind == CXCursor_MacroExpansion)
4788 return clang_getCursorReferenced(C);
4789
4790 if (!clang_isDeclaration(C.kind))
4791 return clang_getNullCursor();
4792
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 if (!D)
4795 return clang_getNullCursor();
4796
4797 switch (D->getKind()) {
4798 // Declaration kinds that don't really separate the notions of
4799 // declaration and definition.
4800 case Decl::Namespace:
4801 case Decl::Typedef:
4802 case Decl::TypeAlias:
4803 case Decl::TypeAliasTemplate:
4804 case Decl::TemplateTypeParm:
4805 case Decl::EnumConstant:
4806 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004807 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 case Decl::IndirectField:
4809 case Decl::ObjCIvar:
4810 case Decl::ObjCAtDefsField:
4811 case Decl::ImplicitParam:
4812 case Decl::ParmVar:
4813 case Decl::NonTypeTemplateParm:
4814 case Decl::TemplateTemplateParm:
4815 case Decl::ObjCCategoryImpl:
4816 case Decl::ObjCImplementation:
4817 case Decl::AccessSpec:
4818 case Decl::LinkageSpec:
4819 case Decl::ObjCPropertyImpl:
4820 case Decl::FileScopeAsm:
4821 case Decl::StaticAssert:
4822 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004823 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 case Decl::Label: // FIXME: Is this right??
4825 case Decl::ClassScopeFunctionSpecialization:
4826 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004827 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 return C;
4829
4830 // Declaration kinds that don't make any sense here, but are
4831 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004832 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 case Decl::TranslationUnit:
4834 break;
4835
4836 // Declaration kinds for which the definition is not resolvable.
4837 case Decl::UnresolvedUsingTypename:
4838 case Decl::UnresolvedUsingValue:
4839 break;
4840
4841 case Decl::UsingDirective:
4842 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4843 TU);
4844
4845 case Decl::NamespaceAlias:
4846 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4847
4848 case Decl::Enum:
4849 case Decl::Record:
4850 case Decl::CXXRecord:
4851 case Decl::ClassTemplateSpecialization:
4852 case Decl::ClassTemplatePartialSpecialization:
4853 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4854 return MakeCXCursor(Def, TU);
4855 return clang_getNullCursor();
4856
4857 case Decl::Function:
4858 case Decl::CXXMethod:
4859 case Decl::CXXConstructor:
4860 case Decl::CXXDestructor:
4861 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004862 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004864 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return clang_getNullCursor();
4866 }
4867
Larisse Voufo39a1e502013-08-06 01:03:05 +00004868 case Decl::Var:
4869 case Decl::VarTemplateSpecialization:
4870 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004872 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 return MakeCXCursor(Def, TU);
4874 return clang_getNullCursor();
4875 }
4876
4877 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004878 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4880 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4881 return clang_getNullCursor();
4882 }
4883
4884 case Decl::ClassTemplate: {
4885 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4886 ->getDefinition())
4887 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4888 TU);
4889 return clang_getNullCursor();
4890 }
4891
Larisse Voufo39a1e502013-08-06 01:03:05 +00004892 case Decl::VarTemplate: {
4893 if (VarDecl *Def =
4894 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4895 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4896 return clang_getNullCursor();
4897 }
4898
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 case Decl::Using:
4900 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4901 D->getLocation(), TU);
4902
4903 case Decl::UsingShadow:
4904 return clang_getCursorDefinition(
4905 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4906 TU));
4907
4908 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 if (Method->isThisDeclarationADefinition())
4911 return C;
4912
4913 // Dig out the method definition in the associated
4914 // @implementation, if we have it.
4915 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4918 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4919 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4920 Method->isInstanceMethod()))
4921 if (Def->isThisDeclarationADefinition())
4922 return MakeCXCursor(Def, TU);
4923
4924 return clang_getNullCursor();
4925 }
4926
4927 case Decl::ObjCCategory:
4928 if (ObjCCategoryImplDecl *Impl
4929 = cast<ObjCCategoryDecl>(D)->getImplementation())
4930 return MakeCXCursor(Impl, TU);
4931 return clang_getNullCursor();
4932
4933 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004934 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 return MakeCXCursor(Def, TU);
4936 return clang_getNullCursor();
4937
4938 case Decl::ObjCInterface: {
4939 // There are two notions of a "definition" for an Objective-C
4940 // class: the interface and its implementation. When we resolved a
4941 // reference to an Objective-C class, produce the @interface as
4942 // the definition; when we were provided with the interface,
4943 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 return MakeCXCursor(Def, TU);
4948 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4949 return MakeCXCursor(Impl, TU);
4950 return clang_getNullCursor();
4951 }
4952
4953 case Decl::ObjCProperty:
4954 // FIXME: We don't really know where to find the
4955 // ObjCPropertyImplDecls that implement this property.
4956 return clang_getNullCursor();
4957
4958 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004959 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004961 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 return MakeCXCursor(Def, TU);
4963
4964 return clang_getNullCursor();
4965
4966 case Decl::Friend:
4967 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4968 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4969 return clang_getNullCursor();
4970
4971 case Decl::FriendTemplate:
4972 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4973 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4974 return clang_getNullCursor();
4975 }
4976
4977 return clang_getNullCursor();
4978}
4979
4980unsigned clang_isCursorDefinition(CXCursor C) {
4981 if (!clang_isDeclaration(C.kind))
4982 return 0;
4983
4984 return clang_getCursorDefinition(C) == C;
4985}
4986
4987CXCursor clang_getCanonicalCursor(CXCursor C) {
4988 if (!clang_isDeclaration(C.kind))
4989 return C;
4990
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 if (const Decl *D = getCursorDecl(C)) {
4992 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4994 return MakeCXCursor(CatD, getCursorTU(C));
4995
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004996 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4997 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 return MakeCXCursor(IFD, getCursorTU(C));
4999
5000 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5001 }
5002
5003 return C;
5004}
5005
5006int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5007 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5008}
5009
5010unsigned clang_getNumOverloadedDecls(CXCursor C) {
5011 if (C.kind != CXCursor_OverloadedDeclRef)
5012 return 0;
5013
5014 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005015 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 return E->getNumDecls();
5017
5018 if (OverloadedTemplateStorage *S
5019 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5020 return S->size();
5021
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005022 const Decl *D = Storage.get<const Decl *>();
5023 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 return Using->shadow_size();
5025
5026 return 0;
5027}
5028
5029CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5030 if (cursor.kind != CXCursor_OverloadedDeclRef)
5031 return clang_getNullCursor();
5032
5033 if (index >= clang_getNumOverloadedDecls(cursor))
5034 return clang_getNullCursor();
5035
5036 CXTranslationUnit TU = getCursorTU(cursor);
5037 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005038 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 return MakeCXCursor(E->decls_begin()[index], TU);
5040
5041 if (OverloadedTemplateStorage *S
5042 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5043 return MakeCXCursor(S->begin()[index], TU);
5044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005045 const Decl *D = Storage.get<const Decl *>();
5046 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 // FIXME: This is, unfortunately, linear time.
5048 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5049 std::advance(Pos, index);
5050 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5051 }
5052
5053 return clang_getNullCursor();
5054}
5055
5056void clang_getDefinitionSpellingAndExtent(CXCursor C,
5057 const char **startBuf,
5058 const char **endBuf,
5059 unsigned *startLine,
5060 unsigned *startColumn,
5061 unsigned *endLine,
5062 unsigned *endColumn) {
5063 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005064 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5066
5067 SourceManager &SM = FD->getASTContext().getSourceManager();
5068 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5069 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5070 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5071 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5072 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5073 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5074}
5075
5076
5077CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5078 unsigned PieceIndex) {
5079 RefNamePieces Pieces;
5080
5081 switch (C.kind) {
5082 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005083 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5085 E->getQualifierLoc().getSourceRange());
5086 break;
5087
5088 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005089 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5091 E->getQualifierLoc().getSourceRange(),
5092 E->getOptionalExplicitTemplateArgs());
5093 break;
5094
5095 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005096 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005098 const Expr *Callee = OCE->getCallee();
5099 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 Callee = ICE->getSubExpr();
5101
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005102 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5104 DRE->getQualifierLoc().getSourceRange());
5105 }
5106 break;
5107
5108 default:
5109 break;
5110 }
5111
5112 if (Pieces.empty()) {
5113 if (PieceIndex == 0)
5114 return clang_getCursorExtent(C);
5115 } else if (PieceIndex < Pieces.size()) {
5116 SourceRange R = Pieces[PieceIndex];
5117 if (R.isValid())
5118 return cxloc::translateSourceRange(getCursorContext(C), R);
5119 }
5120
5121 return clang_getNullRange();
5122}
5123
5124void clang_enableStackTraces(void) {
5125 llvm::sys::PrintStackTraceOnErrorSignal();
5126}
5127
5128void clang_executeOnThread(void (*fn)(void*), void *user_data,
5129 unsigned stack_size) {
5130 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5131}
5132
5133} // end: extern "C"
5134
5135//===----------------------------------------------------------------------===//
5136// Token-based Operations.
5137//===----------------------------------------------------------------------===//
5138
5139/* CXToken layout:
5140 * int_data[0]: a CXTokenKind
5141 * int_data[1]: starting token location
5142 * int_data[2]: token length
5143 * int_data[3]: reserved
5144 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5145 * otherwise unused.
5146 */
5147extern "C" {
5148
5149CXTokenKind clang_getTokenKind(CXToken CXTok) {
5150 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5151}
5152
5153CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5154 switch (clang_getTokenKind(CXTok)) {
5155 case CXToken_Identifier:
5156 case CXToken_Keyword:
5157 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005158 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 ->getNameStart());
5160
5161 case CXToken_Literal: {
5162 // We have stashed the starting pointer in the ptr_data field. Use it.
5163 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005164 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 }
5166
5167 case CXToken_Punctuation:
5168 case CXToken_Comment:
5169 break;
5170 }
5171
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005172 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005173 LOG_BAD_TU(TU);
5174 return cxstring::createEmpty();
5175 }
5176
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 // We have to find the starting buffer pointer the hard way, by
5178 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005179 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005181 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005182
5183 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5184 std::pair<FileID, unsigned> LocInfo
5185 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5186 bool Invalid = false;
5187 StringRef Buffer
5188 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5189 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005190 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005191
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005192 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005193}
5194
5195CXSourceLocation clang_getTokenLocation(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_getNullLocation();
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_getNullLocation();
5204
5205 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5206 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5207}
5208
5209CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005210 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005211 LOG_BAD_TU(TU);
5212 return clang_getNullRange();
5213 }
5214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 if (!CXXUnit)
5217 return clang_getNullRange();
5218
5219 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5220 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5221}
5222
5223static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5224 SmallVectorImpl<CXToken> &CXTokens) {
5225 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5226 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005227 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005229 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005230
5231 // Cannot tokenize across files.
5232 if (BeginLocInfo.first != EndLocInfo.first)
5233 return;
5234
5235 // Create a lexer
5236 bool Invalid = false;
5237 StringRef Buffer
5238 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5239 if (Invalid)
5240 return;
5241
5242 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5243 CXXUnit->getASTContext().getLangOpts(),
5244 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5245 Lex.SetCommentRetentionState(true);
5246
5247 // Lex tokens until we hit the end of the range.
5248 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5249 Token Tok;
5250 bool previousWasAt = false;
5251 do {
5252 // Lex the next token
5253 Lex.LexFromRawLexer(Tok);
5254 if (Tok.is(tok::eof))
5255 break;
5256
5257 // Initialize the CXToken.
5258 CXToken CXTok;
5259
5260 // - Common fields
5261 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5262 CXTok.int_data[2] = Tok.getLength();
5263 CXTok.int_data[3] = 0;
5264
5265 // - Kind-specific fields
5266 if (Tok.isLiteral()) {
5267 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005268 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 } else if (Tok.is(tok::raw_identifier)) {
5270 // Lookup the identifier to determine whether we have a keyword.
5271 IdentifierInfo *II
5272 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5273
5274 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5275 CXTok.int_data[0] = CXToken_Keyword;
5276 }
5277 else {
5278 CXTok.int_data[0] = Tok.is(tok::identifier)
5279 ? CXToken_Identifier
5280 : CXToken_Keyword;
5281 }
5282 CXTok.ptr_data = II;
5283 } else if (Tok.is(tok::comment)) {
5284 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005285 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 } else {
5287 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005288 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 }
5290 CXTokens.push_back(CXTok);
5291 previousWasAt = Tok.is(tok::at);
5292 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5293}
5294
5295void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5296 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005297 LOG_FUNC_SECTION {
5298 *Log << TU << ' ' << Range;
5299 }
5300
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005302 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 if (NumTokens)
5304 *NumTokens = 0;
5305
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005306 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005307 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005308 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005309 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005311 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 if (!CXXUnit || !Tokens || !NumTokens)
5313 return;
5314
5315 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5316
5317 SourceRange R = cxloc::translateCXSourceRange(Range);
5318 if (R.isInvalid())
5319 return;
5320
5321 SmallVector<CXToken, 32> CXTokens;
5322 getTokens(CXXUnit, R, CXTokens);
5323
5324 if (CXTokens.empty())
5325 return;
5326
5327 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5328 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5329 *NumTokens = CXTokens.size();
5330}
5331
5332void clang_disposeTokens(CXTranslationUnit TU,
5333 CXToken *Tokens, unsigned NumTokens) {
5334 free(Tokens);
5335}
5336
5337} // end: extern "C"
5338
5339//===----------------------------------------------------------------------===//
5340// Token annotation APIs.
5341//===----------------------------------------------------------------------===//
5342
Guy Benyei11169dd2012-12-18 14:30:41 +00005343static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5344 CXCursor parent,
5345 CXClientData client_data);
5346static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5347 CXClientData client_data);
5348
5349namespace {
5350class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 CXToken *Tokens;
5352 CXCursor *Cursors;
5353 unsigned NumTokens;
5354 unsigned TokIdx;
5355 unsigned PreprocessingTokIdx;
5356 CursorVisitor AnnotateVis;
5357 SourceManager &SrcMgr;
5358 bool HasContextSensitiveKeywords;
5359
5360 struct PostChildrenInfo {
5361 CXCursor Cursor;
5362 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005363 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 unsigned BeforeChildrenTokenIdx;
5365 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005366 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005367
5368 CXToken &getTok(unsigned Idx) {
5369 assert(Idx < NumTokens);
5370 return Tokens[Idx];
5371 }
5372 const CXToken &getTok(unsigned Idx) const {
5373 assert(Idx < NumTokens);
5374 return Tokens[Idx];
5375 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 bool MoreTokens() const { return TokIdx < NumTokens; }
5377 unsigned NextToken() const { return TokIdx; }
5378 void AdvanceToken() { ++TokIdx; }
5379 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005380 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 }
5382 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005383 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 }
5385 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005386 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 }
5388
5389 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005390 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 SourceRange);
5392
5393public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005394 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005395 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005396 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005397 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005398 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 AnnotateTokensVisitor, this,
5400 /*VisitPreprocessorLast=*/true,
5401 /*VisitIncludedEntities=*/false,
5402 RegionOfInterest,
5403 /*VisitDeclsOnly=*/false,
5404 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005405 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 HasContextSensitiveKeywords(false) { }
5407
5408 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5409 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5410 bool postVisitChildren(CXCursor cursor);
5411 void AnnotateTokens();
5412
5413 /// \brief Determine whether the annotator saw any cursors that have
5414 /// context-sensitive keywords.
5415 bool hasContextSensitiveKeywords() const {
5416 return HasContextSensitiveKeywords;
5417 }
5418
5419 ~AnnotateTokensWorker() {
5420 assert(PostChildrenInfos.empty());
5421 }
5422};
5423}
5424
5425void AnnotateTokensWorker::AnnotateTokens() {
5426 // Walk the AST within the region of interest, annotating tokens
5427 // along the way.
5428 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005429}
Guy Benyei11169dd2012-12-18 14:30:41 +00005430
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005431static inline void updateCursorAnnotation(CXCursor &Cursor,
5432 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005433 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005435 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005436}
5437
5438/// \brief It annotates and advances tokens with a cursor until the comparison
5439//// between the cursor location and the source range is the same as
5440/// \arg compResult.
5441///
5442/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5443/// Pass RangeOverlap to annotate tokens inside a range.
5444void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5445 RangeComparisonResult compResult,
5446 SourceRange range) {
5447 while (MoreTokens()) {
5448 const unsigned I = NextToken();
5449 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005450 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5451 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005452
5453 SourceLocation TokLoc = GetTokenLoc(I);
5454 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005455 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 AdvanceToken();
5457 continue;
5458 }
5459 break;
5460 }
5461}
5462
5463/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005464/// \returns true if it advanced beyond all macro tokens, false otherwise.
5465bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 CXCursor updateC,
5467 RangeComparisonResult compResult,
5468 SourceRange range) {
5469 assert(MoreTokens());
5470 assert(isFunctionMacroToken(NextToken()) &&
5471 "Should be called only for macro arg tokens");
5472
5473 // This works differently than annotateAndAdvanceTokens; because expanded
5474 // macro arguments can have arbitrary translation-unit source order, we do not
5475 // advance the token index one by one until a token fails the range test.
5476 // We only advance once past all of the macro arg tokens if all of them
5477 // pass the range test. If one of them fails we keep the token index pointing
5478 // at the start of the macro arg tokens so that the failing token will be
5479 // annotated by a subsequent annotation try.
5480
5481 bool atLeastOneCompFail = false;
5482
5483 unsigned I = NextToken();
5484 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5485 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5486 if (TokLoc.isFileID())
5487 continue; // not macro arg token, it's parens or comma.
5488 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5489 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5490 Cursors[I] = updateC;
5491 } else
5492 atLeastOneCompFail = true;
5493 }
5494
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005495 if (atLeastOneCompFail)
5496 return false;
5497
5498 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5499 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005500}
5501
5502enum CXChildVisitResult
5503AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 SourceRange cursorRange = getRawCursorExtent(cursor);
5505 if (cursorRange.isInvalid())
5506 return CXChildVisit_Recurse;
5507
5508 if (!HasContextSensitiveKeywords) {
5509 // Objective-C properties can have context-sensitive keywords.
5510 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005511 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5513 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5514 }
5515 // Objective-C methods can have context-sensitive keywords.
5516 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5517 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005518 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5520 if (Method->getObjCDeclQualifier())
5521 HasContextSensitiveKeywords = true;
5522 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005523 for (const auto *P : Method->params()) {
5524 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 HasContextSensitiveKeywords = true;
5526 break;
5527 }
5528 }
5529 }
5530 }
5531 }
5532 // C++ methods can have context-sensitive keywords.
5533 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005534 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5536 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5537 HasContextSensitiveKeywords = true;
5538 }
5539 }
5540 // C++ classes can have context-sensitive keywords.
5541 else if (cursor.kind == CXCursor_StructDecl ||
5542 cursor.kind == CXCursor_ClassDecl ||
5543 cursor.kind == CXCursor_ClassTemplate ||
5544 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005545 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 if (D->hasAttr<FinalAttr>())
5547 HasContextSensitiveKeywords = true;
5548 }
5549 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005550
5551 // Don't override a property annotation with its getter/setter method.
5552 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5553 parent.kind == CXCursor_ObjCPropertyDecl)
5554 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005555
5556 if (clang_isPreprocessing(cursor.kind)) {
5557 // Items in the preprocessing record are kept separate from items in
5558 // declarations, so we keep a separate token index.
5559 unsigned SavedTokIdx = TokIdx;
5560 TokIdx = PreprocessingTokIdx;
5561
5562 // Skip tokens up until we catch up to the beginning of the preprocessing
5563 // entry.
5564 while (MoreTokens()) {
5565 const unsigned I = NextToken();
5566 SourceLocation TokLoc = GetTokenLoc(I);
5567 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5568 case RangeBefore:
5569 AdvanceToken();
5570 continue;
5571 case RangeAfter:
5572 case RangeOverlap:
5573 break;
5574 }
5575 break;
5576 }
5577
5578 // Look at all of the tokens within this range.
5579 while (MoreTokens()) {
5580 const unsigned I = NextToken();
5581 SourceLocation TokLoc = GetTokenLoc(I);
5582 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5583 case RangeBefore:
5584 llvm_unreachable("Infeasible");
5585 case RangeAfter:
5586 break;
5587 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005588 // For macro expansions, just note where the beginning of the macro
5589 // expansion occurs.
5590 if (cursor.kind == CXCursor_MacroExpansion) {
5591 if (TokLoc == cursorRange.getBegin())
5592 Cursors[I] = cursor;
5593 AdvanceToken();
5594 break;
5595 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005596 // We may have already annotated macro names inside macro definitions.
5597 if (Cursors[I].kind != CXCursor_MacroExpansion)
5598 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 continue;
5601 }
5602 break;
5603 }
5604
5605 // Save the preprocessing token index; restore the non-preprocessing
5606 // token index.
5607 PreprocessingTokIdx = TokIdx;
5608 TokIdx = SavedTokIdx;
5609 return CXChildVisit_Recurse;
5610 }
5611
5612 if (cursorRange.isInvalid())
5613 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005614
5615 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 const enum CXCursorKind K = clang_getCursorKind(parent);
5618 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005619 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5620 // Attributes are annotated out-of-order, skip tokens until we reach it.
5621 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 ? clang_getNullCursor() : parent;
5623
5624 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5625
5626 // Avoid having the cursor of an expression "overwrite" the annotation of the
5627 // variable declaration that it belongs to.
5628 // This can happen for C++ constructor expressions whose range generally
5629 // include the variable declaration, e.g.:
5630 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005631 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005632 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005633 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 const unsigned I = NextToken();
5635 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5636 E->getLocStart() == D->getLocation() &&
5637 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005638 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 AdvanceToken();
5640 }
5641 }
5642 }
5643
5644 // Before recursing into the children keep some state that we are going
5645 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5646 // extra work after the child nodes are visited.
5647 // Note that we don't call VisitChildren here to avoid traversing statements
5648 // code-recursively which can blow the stack.
5649
5650 PostChildrenInfo Info;
5651 Info.Cursor = cursor;
5652 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005653 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 Info.BeforeChildrenTokenIdx = NextToken();
5655 PostChildrenInfos.push_back(Info);
5656
5657 return CXChildVisit_Recurse;
5658}
5659
5660bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5661 if (PostChildrenInfos.empty())
5662 return false;
5663 const PostChildrenInfo &Info = PostChildrenInfos.back();
5664 if (!clang_equalCursors(Info.Cursor, cursor))
5665 return false;
5666
5667 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5668 const unsigned AfterChildren = NextToken();
5669 SourceRange cursorRange = Info.CursorRange;
5670
5671 // Scan the tokens that are at the end of the cursor, but are not captured
5672 // but the child cursors.
5673 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5674
5675 // Scan the tokens that are at the beginning of the cursor, but are not
5676 // capture by the child cursors.
5677 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5678 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5679 break;
5680
5681 Cursors[I] = cursor;
5682 }
5683
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005684 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5685 // encountered the attribute cursor.
5686 if (clang_isAttribute(cursor.kind))
5687 TokIdx = Info.BeforeReachingCursorIdx;
5688
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 PostChildrenInfos.pop_back();
5690 return false;
5691}
5692
5693static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5694 CXCursor parent,
5695 CXClientData client_data) {
5696 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5697}
5698
5699static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5700 CXClientData client_data) {
5701 return static_cast<AnnotateTokensWorker*>(client_data)->
5702 postVisitChildren(cursor);
5703}
5704
5705namespace {
5706
5707/// \brief Uses the macro expansions in the preprocessing record to find
5708/// and mark tokens that are macro arguments. This info is used by the
5709/// AnnotateTokensWorker.
5710class MarkMacroArgTokensVisitor {
5711 SourceManager &SM;
5712 CXToken *Tokens;
5713 unsigned NumTokens;
5714 unsigned CurIdx;
5715
5716public:
5717 MarkMacroArgTokensVisitor(SourceManager &SM,
5718 CXToken *tokens, unsigned numTokens)
5719 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5720
5721 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5722 if (cursor.kind != CXCursor_MacroExpansion)
5723 return CXChildVisit_Continue;
5724
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005725 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 if (macroRange.getBegin() == macroRange.getEnd())
5727 return CXChildVisit_Continue; // it's not a function macro.
5728
5729 for (; CurIdx < NumTokens; ++CurIdx) {
5730 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5731 macroRange.getBegin()))
5732 break;
5733 }
5734
5735 if (CurIdx == NumTokens)
5736 return CXChildVisit_Break;
5737
5738 for (; CurIdx < NumTokens; ++CurIdx) {
5739 SourceLocation tokLoc = getTokenLoc(CurIdx);
5740 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5741 break;
5742
5743 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5744 }
5745
5746 if (CurIdx == NumTokens)
5747 return CXChildVisit_Break;
5748
5749 return CXChildVisit_Continue;
5750 }
5751
5752private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005753 CXToken &getTok(unsigned Idx) {
5754 assert(Idx < NumTokens);
5755 return Tokens[Idx];
5756 }
5757 const CXToken &getTok(unsigned Idx) const {
5758 assert(Idx < NumTokens);
5759 return Tokens[Idx];
5760 }
5761
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005763 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 }
5765
5766 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5767 // The third field is reserved and currently not used. Use it here
5768 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005769 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 }
5771};
5772
5773} // end anonymous namespace
5774
5775static CXChildVisitResult
5776MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5777 CXClientData client_data) {
5778 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5779 parent);
5780}
5781
5782namespace {
5783 struct clang_annotateTokens_Data {
5784 CXTranslationUnit TU;
5785 ASTUnit *CXXUnit;
5786 CXToken *Tokens;
5787 unsigned NumTokens;
5788 CXCursor *Cursors;
5789 };
5790}
5791
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005792/// \brief Used by \c annotatePreprocessorTokens.
5793/// \returns true if lexing was finished, false otherwise.
5794static bool lexNext(Lexer &Lex, Token &Tok,
5795 unsigned &NextIdx, unsigned NumTokens) {
5796 if (NextIdx >= NumTokens)
5797 return true;
5798
5799 ++NextIdx;
5800 Lex.LexFromRawLexer(Tok);
5801 if (Tok.is(tok::eof))
5802 return true;
5803
5804 return false;
5805}
5806
Guy Benyei11169dd2012-12-18 14:30:41 +00005807static void annotatePreprocessorTokens(CXTranslationUnit TU,
5808 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005809 CXCursor *Cursors,
5810 CXToken *Tokens,
5811 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005812 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005813
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005814 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5816 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005817 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005819 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005820
5821 if (BeginLocInfo.first != EndLocInfo.first)
5822 return;
5823
5824 StringRef Buffer;
5825 bool Invalid = false;
5826 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5827 if (Buffer.empty() || Invalid)
5828 return;
5829
5830 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5831 CXXUnit->getASTContext().getLangOpts(),
5832 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5833 Buffer.end());
5834 Lex.SetCommentRetentionState(true);
5835
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005836 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 // Lex tokens in raw mode until we hit the end of the range, to avoid
5838 // entering #includes or expanding macros.
5839 while (true) {
5840 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005841 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5842 break;
5843 unsigned TokIdx = NextIdx-1;
5844 assert(Tok.getLocation() ==
5845 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005846
5847 reprocess:
5848 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 // We have found a preprocessing directive. Annotate the tokens
5850 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 //
5852 // FIXME: Some simple tests here could identify macro definitions and
5853 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005854
5855 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005856 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5857 break;
5858
Craig Topper69186e72014-06-08 08:38:04 +00005859 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005860 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005861 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5862 break;
5863
5864 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005865 IdentifierInfo &II =
5866 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005867 SourceLocation MappedTokLoc =
5868 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5869 MI = getMacroInfo(II, MappedTokLoc, TU);
5870 }
5871 }
5872
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005873 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005875 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5876 finished = true;
5877 break;
5878 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005879 // If we are in a macro definition, check if the token was ever a
5880 // macro name and annotate it if that's the case.
5881 if (MI) {
5882 SourceLocation SaveLoc = Tok.getLocation();
5883 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5884 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5885 Tok.setLocation(SaveLoc);
5886 if (MacroDef)
5887 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5888 Tok.getLocation(), TU);
5889 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005890 } while (!Tok.isAtStartOfLine());
5891
5892 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5893 assert(TokIdx <= LastIdx);
5894 SourceLocation EndLoc =
5895 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5896 CXCursor Cursor =
5897 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5898
5899 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005900 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005901
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005902 if (finished)
5903 break;
5904 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 }
5907}
5908
5909// This gets run a separate thread to avoid stack blowout.
5910static void clang_annotateTokensImpl(void *UserData) {
5911 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5912 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5913 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5914 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5915 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5916
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005917 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5919 setThreadBackgroundPriority();
5920
5921 // Determine the region of interest, which contains all of the tokens.
5922 SourceRange RegionOfInterest;
5923 RegionOfInterest.setBegin(
5924 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5925 RegionOfInterest.setEnd(
5926 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5927 Tokens[NumTokens-1])));
5928
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 // Relex the tokens within the source range to look for preprocessing
5930 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005931 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005932
5933 // If begin location points inside a macro argument, set it to the expansion
5934 // location so we can have the full context when annotating semantically.
5935 {
5936 SourceManager &SM = CXXUnit->getSourceManager();
5937 SourceLocation Loc =
5938 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5939 if (Loc.isMacroID())
5940 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5941 }
5942
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5944 // Search and mark tokens that are macro argument expansions.
5945 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5946 Tokens, NumTokens);
5947 CursorVisitor MacroArgMarker(TU,
5948 MarkMacroArgTokensVisitorDelegate, &Visitor,
5949 /*VisitPreprocessorLast=*/true,
5950 /*VisitIncludedEntities=*/false,
5951 RegionOfInterest);
5952 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5953 }
5954
5955 // Annotate all of the source locations in the region of interest that map to
5956 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005957 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005958
5959 // FIXME: We use a ridiculous stack size here because the data-recursion
5960 // algorithm uses a large stack frame than the non-data recursive version,
5961 // and AnnotationTokensWorker currently transforms the data-recursion
5962 // algorithm back into a traditional recursion by explicitly calling
5963 // VisitChildren(). We will need to remove this explicit recursive call.
5964 W.AnnotateTokens();
5965
5966 // If we ran into any entities that involve context-sensitive keywords,
5967 // take another pass through the tokens to mark them as such.
5968 if (W.hasContextSensitiveKeywords()) {
5969 for (unsigned I = 0; I != NumTokens; ++I) {
5970 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5971 continue;
5972
5973 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5974 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005975 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5977 if (Property->getPropertyAttributesAsWritten() != 0 &&
5978 llvm::StringSwitch<bool>(II->getName())
5979 .Case("readonly", true)
5980 .Case("assign", true)
5981 .Case("unsafe_unretained", true)
5982 .Case("readwrite", true)
5983 .Case("retain", true)
5984 .Case("copy", true)
5985 .Case("nonatomic", true)
5986 .Case("atomic", true)
5987 .Case("getter", true)
5988 .Case("setter", true)
5989 .Case("strong", true)
5990 .Case("weak", true)
5991 .Default(false))
5992 Tokens[I].int_data[0] = CXToken_Keyword;
5993 }
5994 continue;
5995 }
5996
5997 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5998 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5999 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6000 if (llvm::StringSwitch<bool>(II->getName())
6001 .Case("in", true)
6002 .Case("out", true)
6003 .Case("inout", true)
6004 .Case("oneway", true)
6005 .Case("bycopy", true)
6006 .Case("byref", true)
6007 .Default(false))
6008 Tokens[I].int_data[0] = CXToken_Keyword;
6009 continue;
6010 }
6011
6012 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6013 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6014 Tokens[I].int_data[0] = CXToken_Keyword;
6015 continue;
6016 }
6017 }
6018 }
6019}
6020
6021extern "C" {
6022
6023void clang_annotateTokens(CXTranslationUnit TU,
6024 CXToken *Tokens, unsigned NumTokens,
6025 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006026 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006027 LOG_BAD_TU(TU);
6028 return;
6029 }
6030 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006031 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006032 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006033 }
6034
6035 LOG_FUNC_SECTION {
6036 *Log << TU << ' ';
6037 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6038 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6039 *Log << clang_getRange(bloc, eloc);
6040 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006041
6042 // Any token we don't specifically annotate will have a NULL cursor.
6043 CXCursor C = clang_getNullCursor();
6044 for (unsigned I = 0; I != NumTokens; ++I)
6045 Cursors[I] = C;
6046
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006047 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 if (!CXXUnit)
6049 return;
6050
6051 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6052
6053 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6054 llvm::CrashRecoveryContext CRC;
6055 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6056 GetSafetyThreadStackSize() * 2)) {
6057 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6058 }
6059}
6060
6061} // end: extern "C"
6062
6063//===----------------------------------------------------------------------===//
6064// Operations for querying linkage of a cursor.
6065//===----------------------------------------------------------------------===//
6066
6067extern "C" {
6068CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6069 if (!clang_isDeclaration(cursor.kind))
6070 return CXLinkage_Invalid;
6071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006072 const Decl *D = cxcursor::getCursorDecl(cursor);
6073 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006074 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006075 case NoLinkage:
6076 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 case InternalLinkage: return CXLinkage_Internal;
6078 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6079 case ExternalLinkage: return CXLinkage_External;
6080 };
6081
6082 return CXLinkage_Invalid;
6083}
6084} // end: extern "C"
6085
6086//===----------------------------------------------------------------------===//
6087// Operations for querying language of a cursor.
6088//===----------------------------------------------------------------------===//
6089
6090static CXLanguageKind getDeclLanguage(const Decl *D) {
6091 if (!D)
6092 return CXLanguage_C;
6093
6094 switch (D->getKind()) {
6095 default:
6096 break;
6097 case Decl::ImplicitParam:
6098 case Decl::ObjCAtDefsField:
6099 case Decl::ObjCCategory:
6100 case Decl::ObjCCategoryImpl:
6101 case Decl::ObjCCompatibleAlias:
6102 case Decl::ObjCImplementation:
6103 case Decl::ObjCInterface:
6104 case Decl::ObjCIvar:
6105 case Decl::ObjCMethod:
6106 case Decl::ObjCProperty:
6107 case Decl::ObjCPropertyImpl:
6108 case Decl::ObjCProtocol:
6109 return CXLanguage_ObjC;
6110 case Decl::CXXConstructor:
6111 case Decl::CXXConversion:
6112 case Decl::CXXDestructor:
6113 case Decl::CXXMethod:
6114 case Decl::CXXRecord:
6115 case Decl::ClassTemplate:
6116 case Decl::ClassTemplatePartialSpecialization:
6117 case Decl::ClassTemplateSpecialization:
6118 case Decl::Friend:
6119 case Decl::FriendTemplate:
6120 case Decl::FunctionTemplate:
6121 case Decl::LinkageSpec:
6122 case Decl::Namespace:
6123 case Decl::NamespaceAlias:
6124 case Decl::NonTypeTemplateParm:
6125 case Decl::StaticAssert:
6126 case Decl::TemplateTemplateParm:
6127 case Decl::TemplateTypeParm:
6128 case Decl::UnresolvedUsingTypename:
6129 case Decl::UnresolvedUsingValue:
6130 case Decl::Using:
6131 case Decl::UsingDirective:
6132 case Decl::UsingShadow:
6133 return CXLanguage_CPlusPlus;
6134 }
6135
6136 return CXLanguage_C;
6137}
6138
6139extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006140
6141static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6142 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6143 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006144
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006145 switch (D->getAvailability()) {
6146 case AR_Available:
6147 case AR_NotYetIntroduced:
6148 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006149 return getCursorAvailabilityForDecl(
6150 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006151 return CXAvailability_Available;
6152
6153 case AR_Deprecated:
6154 return CXAvailability_Deprecated;
6155
6156 case AR_Unavailable:
6157 return CXAvailability_NotAvailable;
6158 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006159
6160 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006161}
6162
Guy Benyei11169dd2012-12-18 14:30:41 +00006163enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6164 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006165 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6166 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006167
6168 return CXAvailability_Available;
6169}
6170
6171static CXVersion convertVersion(VersionTuple In) {
6172 CXVersion Out = { -1, -1, -1 };
6173 if (In.empty())
6174 return Out;
6175
6176 Out.Major = In.getMajor();
6177
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006178 Optional<unsigned> Minor = In.getMinor();
6179 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 Out.Minor = *Minor;
6181 else
6182 return Out;
6183
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006184 Optional<unsigned> Subminor = In.getSubminor();
6185 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 Out.Subminor = *Subminor;
6187
6188 return Out;
6189}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006190
6191static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6192 int *always_deprecated,
6193 CXString *deprecated_message,
6194 int *always_unavailable,
6195 CXString *unavailable_message,
6196 CXPlatformAvailability *availability,
6197 int availability_size) {
6198 bool HadAvailAttr = false;
6199 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006200 for (auto A : D->attrs()) {
6201 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006202 HadAvailAttr = true;
6203 if (always_deprecated)
6204 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006205 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006206 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006207 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006208 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006209 continue;
6210 }
6211
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006212 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006213 HadAvailAttr = true;
6214 if (always_unavailable)
6215 *always_unavailable = 1;
6216 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006217 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006218 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6219 }
6220 continue;
6221 }
6222
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006223 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006224 HadAvailAttr = true;
6225 if (N < availability_size) {
6226 availability[N].Platform
6227 = cxstring::createDup(Avail->getPlatform()->getName());
6228 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6229 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6230 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6231 availability[N].Unavailable = Avail->getUnavailable();
6232 availability[N].Message = cxstring::createDup(Avail->getMessage());
6233 }
6234 ++N;
6235 }
6236 }
6237
6238 if (!HadAvailAttr)
6239 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6240 return getCursorPlatformAvailabilityForDecl(
6241 cast<Decl>(EnumConst->getDeclContext()),
6242 always_deprecated,
6243 deprecated_message,
6244 always_unavailable,
6245 unavailable_message,
6246 availability,
6247 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006249 return N;
6250}
6251
Guy Benyei11169dd2012-12-18 14:30:41 +00006252int clang_getCursorPlatformAvailability(CXCursor cursor,
6253 int *always_deprecated,
6254 CXString *deprecated_message,
6255 int *always_unavailable,
6256 CXString *unavailable_message,
6257 CXPlatformAvailability *availability,
6258 int availability_size) {
6259 if (always_deprecated)
6260 *always_deprecated = 0;
6261 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006262 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006263 if (always_unavailable)
6264 *always_unavailable = 0;
6265 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006266 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006267
Guy Benyei11169dd2012-12-18 14:30:41 +00006268 if (!clang_isDeclaration(cursor.kind))
6269 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006271 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006272 if (!D)
6273 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006274
6275 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6276 deprecated_message,
6277 always_unavailable,
6278 unavailable_message,
6279 availability,
6280 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006281}
6282
6283void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6284 clang_disposeString(availability->Platform);
6285 clang_disposeString(availability->Message);
6286}
6287
6288CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6289 if (clang_isDeclaration(cursor.kind))
6290 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6291
6292 return CXLanguage_Invalid;
6293}
6294
6295 /// \brief If the given cursor is the "templated" declaration
6296 /// descibing a class or function template, return the class or
6297 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006298static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006300 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006302 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6304 return FunTmpl;
6305
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006306 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6308 return ClassTmpl;
6309
6310 return D;
6311}
6312
6313CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6314 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006315 if (const Decl *D = getCursorDecl(cursor)) {
6316 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 if (!DC)
6318 return clang_getNullCursor();
6319
6320 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6321 getCursorTU(cursor));
6322 }
6323 }
6324
6325 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006326 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 return MakeCXCursor(D, getCursorTU(cursor));
6328 }
6329
6330 return clang_getNullCursor();
6331}
6332
6333CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6334 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006335 if (const Decl *D = getCursorDecl(cursor)) {
6336 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 if (!DC)
6338 return clang_getNullCursor();
6339
6340 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6341 getCursorTU(cursor));
6342 }
6343 }
6344
6345 // FIXME: Note that we can't easily compute the lexical context of a
6346 // statement or expression, so we return nothing.
6347 return clang_getNullCursor();
6348}
6349
6350CXFile clang_getIncludedFile(CXCursor cursor) {
6351 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006352 return nullptr;
6353
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006354 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006355 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006356}
6357
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006358unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6359 if (C.kind != CXCursor_ObjCPropertyDecl)
6360 return CXObjCPropertyAttr_noattr;
6361
6362 unsigned Result = CXObjCPropertyAttr_noattr;
6363 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6364 ObjCPropertyDecl::PropertyAttributeKind Attr =
6365 PD->getPropertyAttributesAsWritten();
6366
6367#define SET_CXOBJCPROP_ATTR(A) \
6368 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6369 Result |= CXObjCPropertyAttr_##A
6370 SET_CXOBJCPROP_ATTR(readonly);
6371 SET_CXOBJCPROP_ATTR(getter);
6372 SET_CXOBJCPROP_ATTR(assign);
6373 SET_CXOBJCPROP_ATTR(readwrite);
6374 SET_CXOBJCPROP_ATTR(retain);
6375 SET_CXOBJCPROP_ATTR(copy);
6376 SET_CXOBJCPROP_ATTR(nonatomic);
6377 SET_CXOBJCPROP_ATTR(setter);
6378 SET_CXOBJCPROP_ATTR(atomic);
6379 SET_CXOBJCPROP_ATTR(weak);
6380 SET_CXOBJCPROP_ATTR(strong);
6381 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6382#undef SET_CXOBJCPROP_ATTR
6383
6384 return Result;
6385}
6386
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006387unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6388 if (!clang_isDeclaration(C.kind))
6389 return CXObjCDeclQualifier_None;
6390
6391 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6392 const Decl *D = getCursorDecl(C);
6393 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6394 QT = MD->getObjCDeclQualifier();
6395 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6396 QT = PD->getObjCDeclQualifier();
6397 if (QT == Decl::OBJC_TQ_None)
6398 return CXObjCDeclQualifier_None;
6399
6400 unsigned Result = CXObjCDeclQualifier_None;
6401 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6402 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6403 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6404 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6405 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6406 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6407
6408 return Result;
6409}
6410
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006411unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6412 if (!clang_isDeclaration(C.kind))
6413 return 0;
6414
6415 const Decl *D = getCursorDecl(C);
6416 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6417 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6418 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6419 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6420
6421 return 0;
6422}
6423
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006424unsigned clang_Cursor_isVariadic(CXCursor C) {
6425 if (!clang_isDeclaration(C.kind))
6426 return 0;
6427
6428 const Decl *D = getCursorDecl(C);
6429 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6430 return FD->isVariadic();
6431 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6432 return MD->isVariadic();
6433
6434 return 0;
6435}
6436
Guy Benyei11169dd2012-12-18 14:30:41 +00006437CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6438 if (!clang_isDeclaration(C.kind))
6439 return clang_getNullRange();
6440
6441 const Decl *D = getCursorDecl(C);
6442 ASTContext &Context = getCursorContext(C);
6443 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6444 if (!RC)
6445 return clang_getNullRange();
6446
6447 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6448}
6449
6450CXString clang_Cursor_getRawCommentText(CXCursor C) {
6451 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006452 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006453
6454 const Decl *D = getCursorDecl(C);
6455 ASTContext &Context = getCursorContext(C);
6456 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6457 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6458 StringRef();
6459
6460 // Don't duplicate the string because RawText points directly into source
6461 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006462 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006463}
6464
6465CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6466 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006467 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006468
6469 const Decl *D = getCursorDecl(C);
6470 const ASTContext &Context = getCursorContext(C);
6471 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6472
6473 if (RC) {
6474 StringRef BriefText = RC->getBriefText(Context);
6475
6476 // Don't duplicate the string because RawComment ensures that this memory
6477 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006478 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006479 }
6480
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006481 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006482}
6483
Guy Benyei11169dd2012-12-18 14:30:41 +00006484CXModule clang_Cursor_getModule(CXCursor C) {
6485 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006486 if (const ImportDecl *ImportD =
6487 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 return ImportD->getImportedModule();
6489 }
6490
Craig Topper69186e72014-06-08 08:38:04 +00006491 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006492}
6493
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006494CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6495 if (isNotUsableTU(TU)) {
6496 LOG_BAD_TU(TU);
6497 return nullptr;
6498 }
6499 if (!File)
6500 return nullptr;
6501 FileEntry *FE = static_cast<FileEntry *>(File);
6502
6503 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6504 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6505 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6506
6507 if (Module *Mod = Header.getModule()) {
6508 if (Header.getRole() != ModuleMap::ExcludedHeader)
6509 return Mod;
6510 }
6511 return nullptr;
6512}
6513
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006514CXFile clang_Module_getASTFile(CXModule CXMod) {
6515 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006516 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006517 Module *Mod = static_cast<Module*>(CXMod);
6518 return const_cast<FileEntry *>(Mod->getASTFile());
6519}
6520
Guy Benyei11169dd2012-12-18 14:30:41 +00006521CXModule clang_Module_getParent(CXModule CXMod) {
6522 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006523 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 Module *Mod = static_cast<Module*>(CXMod);
6525 return Mod->Parent;
6526}
6527
6528CXString clang_Module_getName(CXModule CXMod) {
6529 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006530 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006532 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006533}
6534
6535CXString clang_Module_getFullName(CXModule CXMod) {
6536 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006537 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006539 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006540}
6541
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006542int clang_Module_isSystem(CXModule CXMod) {
6543 if (!CXMod)
6544 return 0;
6545 Module *Mod = static_cast<Module*>(CXMod);
6546 return Mod->IsSystem;
6547}
6548
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006549unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6550 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006551 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006552 LOG_BAD_TU(TU);
6553 return 0;
6554 }
6555 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006556 return 0;
6557 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006558 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6559 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6560 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006561}
6562
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006563CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6564 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006565 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006566 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006567 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006568 }
6569 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006570 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006572 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006574 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6575 if (Index < TopHeaders.size())
6576 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006577
Craig Topper69186e72014-06-08 08:38:04 +00006578 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006579}
6580
6581} // end: extern "C"
6582
6583//===----------------------------------------------------------------------===//
6584// C++ AST instrospection.
6585//===----------------------------------------------------------------------===//
6586
6587extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006588unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6589 if (!clang_isDeclaration(C.kind))
6590 return 0;
6591
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006592 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006593 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006594 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006595 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6596}
6597
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006598unsigned clang_CXXMethod_isConst(CXCursor C) {
6599 if (!clang_isDeclaration(C.kind))
6600 return 0;
6601
6602 const Decl *D = cxcursor::getCursorDecl(C);
6603 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006604 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006605 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6606}
6607
Guy Benyei11169dd2012-12-18 14:30:41 +00006608unsigned clang_CXXMethod_isStatic(CXCursor C) {
6609 if (!clang_isDeclaration(C.kind))
6610 return 0;
6611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006612 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006613 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006614 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 return (Method && Method->isStatic()) ? 1 : 0;
6616}
6617
6618unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6619 if (!clang_isDeclaration(C.kind))
6620 return 0;
6621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006622 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006623 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006624 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 return (Method && Method->isVirtual()) ? 1 : 0;
6626}
6627} // end: extern "C"
6628
6629//===----------------------------------------------------------------------===//
6630// Attribute introspection.
6631//===----------------------------------------------------------------------===//
6632
6633extern "C" {
6634CXType clang_getIBOutletCollectionType(CXCursor C) {
6635 if (C.kind != CXCursor_IBOutletCollectionAttr)
6636 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6637
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006638 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6640
6641 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6642}
6643} // end: extern "C"
6644
6645//===----------------------------------------------------------------------===//
6646// Inspecting memory usage.
6647//===----------------------------------------------------------------------===//
6648
6649typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6650
6651static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6652 enum CXTUResourceUsageKind k,
6653 unsigned long amount) {
6654 CXTUResourceUsageEntry entry = { k, amount };
6655 entries.push_back(entry);
6656}
6657
6658extern "C" {
6659
6660const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6661 const char *str = "";
6662 switch (kind) {
6663 case CXTUResourceUsage_AST:
6664 str = "ASTContext: expressions, declarations, and types";
6665 break;
6666 case CXTUResourceUsage_Identifiers:
6667 str = "ASTContext: identifiers";
6668 break;
6669 case CXTUResourceUsage_Selectors:
6670 str = "ASTContext: selectors";
6671 break;
6672 case CXTUResourceUsage_GlobalCompletionResults:
6673 str = "Code completion: cached global results";
6674 break;
6675 case CXTUResourceUsage_SourceManagerContentCache:
6676 str = "SourceManager: content cache allocator";
6677 break;
6678 case CXTUResourceUsage_AST_SideTables:
6679 str = "ASTContext: side tables";
6680 break;
6681 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6682 str = "SourceManager: malloc'ed memory buffers";
6683 break;
6684 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6685 str = "SourceManager: mmap'ed memory buffers";
6686 break;
6687 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6688 str = "ExternalASTSource: malloc'ed memory buffers";
6689 break;
6690 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6691 str = "ExternalASTSource: mmap'ed memory buffers";
6692 break;
6693 case CXTUResourceUsage_Preprocessor:
6694 str = "Preprocessor: malloc'ed memory";
6695 break;
6696 case CXTUResourceUsage_PreprocessingRecord:
6697 str = "Preprocessor: PreprocessingRecord";
6698 break;
6699 case CXTUResourceUsage_SourceManager_DataStructures:
6700 str = "SourceManager: data structures and tables";
6701 break;
6702 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6703 str = "Preprocessor: header search tables";
6704 break;
6705 }
6706 return str;
6707}
6708
6709CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006710 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006711 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006712 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 return usage;
6714 }
6715
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006716 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006717 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006718 ASTContext &astContext = astUnit->getASTContext();
6719
6720 // How much memory is used by AST nodes and types?
6721 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6722 (unsigned long) astContext.getASTAllocatedMemory());
6723
6724 // How much memory is used by identifiers?
6725 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6726 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6727
6728 // How much memory is used for selectors?
6729 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6730 (unsigned long) astContext.Selectors.getTotalMemory());
6731
6732 // How much memory is used by ASTContext's side tables?
6733 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6734 (unsigned long) astContext.getSideTableAllocatedMemory());
6735
6736 // How much memory is used for caching global code completion results?
6737 unsigned long completionBytes = 0;
6738 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006739 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006740 completionBytes = completionAllocator->getTotalMemory();
6741 }
6742 createCXTUResourceUsageEntry(*entries,
6743 CXTUResourceUsage_GlobalCompletionResults,
6744 completionBytes);
6745
6746 // How much memory is being used by SourceManager's content cache?
6747 createCXTUResourceUsageEntry(*entries,
6748 CXTUResourceUsage_SourceManagerContentCache,
6749 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6750
6751 // How much memory is being used by the MemoryBuffer's in SourceManager?
6752 const SourceManager::MemoryBufferSizes &srcBufs =
6753 astUnit->getSourceManager().getMemoryBufferSizes();
6754
6755 createCXTUResourceUsageEntry(*entries,
6756 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6757 (unsigned long) srcBufs.malloc_bytes);
6758 createCXTUResourceUsageEntry(*entries,
6759 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6760 (unsigned long) srcBufs.mmap_bytes);
6761 createCXTUResourceUsageEntry(*entries,
6762 CXTUResourceUsage_SourceManager_DataStructures,
6763 (unsigned long) astContext.getSourceManager()
6764 .getDataStructureSizes());
6765
6766 // How much memory is being used by the ExternalASTSource?
6767 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6768 const ExternalASTSource::MemoryBufferSizes &sizes =
6769 esrc->getMemoryBufferSizes();
6770
6771 createCXTUResourceUsageEntry(*entries,
6772 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6773 (unsigned long) sizes.malloc_bytes);
6774 createCXTUResourceUsageEntry(*entries,
6775 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6776 (unsigned long) sizes.mmap_bytes);
6777 }
6778
6779 // How much memory is being used by the Preprocessor?
6780 Preprocessor &pp = astUnit->getPreprocessor();
6781 createCXTUResourceUsageEntry(*entries,
6782 CXTUResourceUsage_Preprocessor,
6783 pp.getTotalMemory());
6784
6785 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6786 createCXTUResourceUsageEntry(*entries,
6787 CXTUResourceUsage_PreprocessingRecord,
6788 pRec->getTotalMemory());
6789 }
6790
6791 createCXTUResourceUsageEntry(*entries,
6792 CXTUResourceUsage_Preprocessor_HeaderSearch,
6793 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006794
Guy Benyei11169dd2012-12-18 14:30:41 +00006795 CXTUResourceUsage usage = { (void*) entries.get(),
6796 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006797 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006798 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 return usage;
6800}
6801
6802void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6803 if (usage.data)
6804 delete (MemUsageEntries*) usage.data;
6805}
6806
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006807CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6808 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006809 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006810 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006811
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006812 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006813 LOG_BAD_TU(TU);
6814 return skipped;
6815 }
6816
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006817 if (!file)
6818 return skipped;
6819
6820 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6821 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6822 if (!ppRec)
6823 return skipped;
6824
6825 ASTContext &Ctx = astUnit->getASTContext();
6826 SourceManager &sm = Ctx.getSourceManager();
6827 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6828 FileID wantedFileID = sm.translateFile(fileEntry);
6829
6830 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6831 std::vector<SourceRange> wantedRanges;
6832 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6833 i != ei; ++i) {
6834 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6835 wantedRanges.push_back(*i);
6836 }
6837
6838 skipped->count = wantedRanges.size();
6839 skipped->ranges = new CXSourceRange[skipped->count];
6840 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6841 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6842
6843 return skipped;
6844}
6845
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006846void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6847 if (ranges) {
6848 delete[] ranges->ranges;
6849 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006850 }
6851}
6852
Guy Benyei11169dd2012-12-18 14:30:41 +00006853} // end extern "C"
6854
6855void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6856 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6857 for (unsigned I = 0; I != Usage.numEntries; ++I)
6858 fprintf(stderr, " %s: %lu\n",
6859 clang_getTUResourceUsageName(Usage.entries[I].kind),
6860 Usage.entries[I].amount);
6861
6862 clang_disposeCXTUResourceUsage(Usage);
6863}
6864
6865//===----------------------------------------------------------------------===//
6866// Misc. utility functions.
6867//===----------------------------------------------------------------------===//
6868
6869/// Default to using an 8 MB stack size on "safety" threads.
6870static unsigned SafetyStackThreadSize = 8 << 20;
6871
6872namespace clang {
6873
6874bool RunSafely(llvm::CrashRecoveryContext &CRC,
6875 void (*Fn)(void*), void *UserData,
6876 unsigned Size) {
6877 if (!Size)
6878 Size = GetSafetyThreadStackSize();
6879 if (Size)
6880 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6881 return CRC.RunSafely(Fn, UserData);
6882}
6883
6884unsigned GetSafetyThreadStackSize() {
6885 return SafetyStackThreadSize;
6886}
6887
6888void SetSafetyThreadStackSize(unsigned Value) {
6889 SafetyStackThreadSize = Value;
6890}
6891
6892}
6893
6894void clang::setThreadBackgroundPriority() {
6895 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6896 return;
6897
Alp Toker1a86ad22014-07-06 06:24:00 +00006898#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006899 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6900#endif
6901}
6902
6903void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6904 if (!Unit)
6905 return;
6906
6907 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6908 DEnd = Unit->stored_diag_end();
6909 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006910 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006911 CXString Msg = clang_formatDiagnostic(&Diag,
6912 clang_defaultDiagnosticDisplayOptions());
6913 fprintf(stderr, "%s\n", clang_getCString(Msg));
6914 clang_disposeString(Msg);
6915 }
6916#ifdef LLVM_ON_WIN32
6917 // On Windows, force a flush, since there may be multiple copies of
6918 // stderr and stdout in the file system, all with different buffers
6919 // but writing to the same device.
6920 fflush(stderr);
6921#endif
6922}
6923
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006924MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6925 SourceLocation MacroDefLoc,
6926 CXTranslationUnit TU){
6927 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006929 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006930 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006931
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006932 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006933 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006934 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006935 if (MD) {
6936 for (MacroDirective::DefInfo
6937 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6938 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6939 return Def.getMacroInfo();
6940 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006941 }
6942
Craig Topper69186e72014-06-08 08:38:04 +00006943 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006944}
6945
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006946const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6947 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006948 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006949 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006950 const IdentifierInfo *II = MacroDef->getName();
6951 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006953
6954 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6955}
6956
6957MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6958 const Token &Tok,
6959 CXTranslationUnit TU) {
6960 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006961 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006962 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006963 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006964
6965 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006966 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006967 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6968 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006969 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006970
6971 // Check that the token is inside the definition and not its argument list.
6972 SourceManager &SM = Unit->getSourceManager();
6973 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006974 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006975 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006976 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006977
6978 Preprocessor &PP = Unit->getPreprocessor();
6979 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6980 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006981 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006982
Alp Toker2d57cea2014-05-17 04:53:25 +00006983 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006984 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006985 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006986
6987 // Check that the identifier is not one of the macro arguments.
6988 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006989 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006990
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006991 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6992 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006993 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006994
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006995 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006996}
6997
6998MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6999 SourceLocation Loc,
7000 CXTranslationUnit TU) {
7001 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007002 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007003
7004 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007005 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007006 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007007 Preprocessor &PP = Unit->getPreprocessor();
7008 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007009 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007010 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7011 Token Tok;
7012 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007013 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007014
7015 return checkForMacroInMacroDefinition(MI, Tok, TU);
7016}
7017
Guy Benyei11169dd2012-12-18 14:30:41 +00007018extern "C" {
7019
7020CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007021 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007022}
7023
7024} // end: extern "C"
7025
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007026Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7027 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007028 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007029 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007030 if (Unit->isMainFileAST())
7031 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007032 return *this;
7033 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007034 } else {
7035 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007036 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007037 return *this;
7038}
7039
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007040Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7041 *this << FE->getName();
7042 return *this;
7043}
7044
7045Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7046 CXString cursorName = clang_getCursorDisplayName(cursor);
7047 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7048 clang_disposeString(cursorName);
7049 return *this;
7050}
7051
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007052Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7053 CXFile File;
7054 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007055 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007056 CXString FileName = clang_getFileName(File);
7057 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7058 clang_disposeString(FileName);
7059 return *this;
7060}
7061
7062Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7063 CXSourceLocation BLoc = clang_getRangeStart(range);
7064 CXSourceLocation ELoc = clang_getRangeEnd(range);
7065
7066 CXFile BFile;
7067 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007068 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007069
7070 CXFile EFile;
7071 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007072 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007073
7074 CXString BFileName = clang_getFileName(BFile);
7075 if (BFile == EFile) {
7076 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7077 BLine, BColumn, ELine, EColumn);
7078 } else {
7079 CXString EFileName = clang_getFileName(EFile);
7080 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7081 BLine, BColumn)
7082 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7083 ELine, EColumn);
7084 clang_disposeString(EFileName);
7085 }
7086 clang_disposeString(BFileName);
7087 return *this;
7088}
7089
7090Logger &cxindex::Logger::operator<<(CXString Str) {
7091 *this << clang_getCString(Str);
7092 return *this;
7093}
7094
7095Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7096 LogOS << Fmt;
7097 return *this;
7098}
7099
Chandler Carruth37ad2582014-06-27 15:14:39 +00007100static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7101
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007102cxindex::Logger::~Logger() {
7103 LogOS.flush();
7104
Chandler Carruth37ad2582014-06-27 15:14:39 +00007105 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007106
7107 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7108
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007109 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007110 OS << "[libclang:" << Name << ':';
7111
Alp Toker1a86ad22014-07-06 06:24:00 +00007112#ifdef USE_DARWIN_THREADS
7113 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007114 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7115 OS << tid << ':';
7116#endif
7117
7118 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7119 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7120 OS << Msg.str() << '\n';
7121
7122 if (Trace) {
7123 llvm::sys::PrintStackTrace(stderr);
7124 OS << "--------------------------------------------------\n";
7125 }
7126}