blob: e5a438bd302ddef600a80eed1b17833a52648ce2 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001787 case Stmt::OMPCriticalDirectiveClass:
1788 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001861 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001862 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001863 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001864 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001865 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001866 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001867 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001868 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001869 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001870 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001871 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001872 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001873 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001874 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001875 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876
Guy Benyei11169dd2012-12-18 14:30:41 +00001877private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1880 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1882 void AddStmt(const Stmt *S);
1883 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001886 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888} // end anonyous namespace
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 // 'S' should always be non-null, since it comes from the
1892 // statement we are visiting.
1893 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1894}
1895
1896void
1897EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1898 if (Qualifier)
1899 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1900}
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (S)
1904 WL.push_back(StmtVisit(S, Parent));
1905}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (D)
1908 WL.push_back(DeclVisit(D, Parent, isFirst));
1909}
1910void EnqueueVisitor::
1911 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1912 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001914}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001915void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 if (D)
1917 WL.push_back(MemberRefVisit(D, L, Parent));
1918}
1919void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1920 if (TI)
1921 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1922 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 AddStmt(*Child);
1927 }
1928 if (size == WL.size())
1929 return;
1930 // Now reverse the entries we just added. This will match the DFS
1931 // ordering performed by the worklist.
1932 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1933 std::reverse(I, E);
1934}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935namespace {
1936class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1937 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001938 /// \brief Process clauses with list of variables.
1939 template <typename T>
1940 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941public:
1942 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1943#define OPENMP_CLAUSE(Name, Class) \
1944 void Visit##Class(const Class *C);
1945#include "clang/Basic/OpenMPKinds.def"
1946};
1947
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001948void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1949 Visitor->AddStmt(C->getCondition());
1950}
1951
Alexey Bataev3778b602014-07-17 07:32:53 +00001952void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev568a8332014-03-06 06:15:19 +00001956void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1957 Visitor->AddStmt(C->getNumThreads());
1958}
1959
Alexey Bataev62c87d22014-03-21 04:51:18 +00001960void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1961 Visitor->AddStmt(C->getSafelen());
1962}
1963
Alexander Musman8bd31e62014-05-27 15:12:19 +00001964void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1965 Visitor->AddStmt(C->getNumForLoops());
1966}
1967
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001969
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001970void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1971
Alexey Bataev56dafe82014-06-20 07:16:17 +00001972void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1973 Visitor->AddStmt(C->getChunkSize());
1974}
1975
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001976void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1977
Alexey Bataev236070f2014-06-20 11:19:47 +00001978void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1979
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001980void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1981
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001982void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1983
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001984void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1985
Alexey Bataevdea47612014-07-23 07:46:59 +00001986void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1987
Alexey Bataev67a4f222014-07-23 10:25:33 +00001988void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1989
Alexey Bataev459dec02014-07-24 06:46:57 +00001990void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1991
Alexey Bataev756c1962013-09-24 03:17:45 +00001992template<typename T>
1993void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001994 for (const auto *I : Node->varlists())
1995 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001996}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001997
1998void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001999 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002000}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002001void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2002 const OMPFirstprivateClause *C) {
2003 VisitOMPClauseList(C);
2004}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002005void OMPClauseEnqueue::VisitOMPLastprivateClause(
2006 const OMPLastprivateClause *C) {
2007 VisitOMPClauseList(C);
2008}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002009void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002010 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002011}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002012void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexander Musman8dba6642014-04-22 13:09:42 +00002015void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2016 VisitOMPClauseList(C);
2017 Visitor->AddStmt(C->getStep());
2018}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002019void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2020 VisitOMPClauseList(C);
2021 Visitor->AddStmt(C->getAlignment());
2022}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002023void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2024 VisitOMPClauseList(C);
2025}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002026void
2027OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2028 VisitOMPClauseList(C);
2029}
Alexey Bataev6125da92014-07-21 11:26:11 +00002030void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2031 VisitOMPClauseList(C);
2032}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002033}
Alexey Bataev756c1962013-09-24 03:17:45 +00002034
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002035void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2036 unsigned size = WL.size();
2037 OMPClauseEnqueue Visitor(this);
2038 Visitor.Visit(S);
2039 if (size == WL.size())
2040 return;
2041 // Now reverse the entries we just added. This will match the DFS
2042 // ordering performed by the worklist.
2043 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2044 std::reverse(I, E);
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 AddDecl(B->getBlockDecl());
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 EnqueueChildren(E);
2054 AddTypeLoc(E->getTypeSourceInfo());
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2057 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 E = S->body_rend(); I != E; ++I) {
2059 AddStmt(*I);
2060 }
2061}
2062void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 AddStmt(S->getSubStmt());
2065 AddDeclarationNameInfo(S);
2066 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2067 AddNestedNameSpecifierLoc(QualifierLoc);
2068}
2069
2070void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2073 AddDeclarationNameInfo(E);
2074 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2075 AddNestedNameSpecifierLoc(QualifierLoc);
2076 if (!E->isImplicitAccess())
2077 AddStmt(E->getBase());
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 // Enqueue the initializer , if any.
2081 AddStmt(E->getInitializer());
2082 // Enqueue the array size, if any.
2083 AddStmt(E->getArraySize());
2084 // Enqueue the allocated type.
2085 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2086 // Enqueue the placement arguments.
2087 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2088 AddStmt(E->getPlacementArg(I-1));
2089}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002091 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2092 AddStmt(CE->getArg(I-1));
2093 AddStmt(CE->getCallee());
2094 AddStmt(CE->getArg(0));
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2097 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 // Visit the name of the type being destroyed.
2099 AddTypeLoc(E->getDestroyedTypeInfo());
2100 // Visit the scope type that looks disturbingly like the nested-name-specifier
2101 // but isn't.
2102 AddTypeLoc(E->getScopeTypeInfo());
2103 // Visit the nested-name-specifier.
2104 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2105 AddNestedNameSpecifierLoc(QualifierLoc);
2106 // Visit base expression.
2107 AddStmt(E->getBase());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2110 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddTypeLoc(E->getTypeSourceInfo());
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2114 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 EnqueueChildren(E);
2116 AddTypeLoc(E->getTypeSourceInfo());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 EnqueueChildren(E);
2120 if (E->isTypeOperand())
2121 AddTypeLoc(E->getTypeOperandSourceInfo());
2122}
2123
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2125 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 EnqueueChildren(E);
2127 AddTypeLoc(E->getTypeSourceInfo());
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 EnqueueChildren(E);
2131 if (E->isTypeOperand())
2132 AddTypeLoc(E->getTypeOperandSourceInfo());
2133}
2134
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(S);
2137 AddDecl(S->getExceptionDecl());
2138}
2139
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 if (DR->hasExplicitTemplateArgs()) {
2142 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2143 }
2144 WL.push_back(DeclRefExprParts(DR, Parent));
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2147 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2149 AddDeclarationNameInfo(E);
2150 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 unsigned size = WL.size();
2154 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002155 for (const auto *D : S->decls()) {
2156 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 isFirst = false;
2158 }
2159 if (size == WL.size())
2160 return;
2161 // Now reverse the entries we just added. This will match the DFS
2162 // ordering performed by the worklist.
2163 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2164 std::reverse(I, E);
2165}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 D = E->designators_rbegin(), DEnd = E->designators_rend();
2170 D != DEnd; ++D) {
2171 if (D->isFieldDesignator()) {
2172 if (FieldDecl *Field = D->getField())
2173 AddMemberRef(Field, D->getFieldLoc());
2174 continue;
2175 }
2176 if (D->isArrayDesignator()) {
2177 AddStmt(E->getArrayIndex(*D));
2178 continue;
2179 }
2180 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2181 AddStmt(E->getArrayRangeEnd(*D));
2182 AddStmt(E->getArrayRangeStart(*D));
2183 }
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(E);
2187 AddTypeLoc(E->getTypeInfoAsWritten());
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddStmt(FS->getBody());
2191 AddStmt(FS->getInc());
2192 AddStmt(FS->getCond());
2193 AddDecl(FS->getConditionVariable());
2194 AddStmt(FS->getInit());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddStmt(If->getElse());
2201 AddStmt(If->getThen());
2202 AddStmt(If->getCond());
2203 AddDecl(If->getConditionVariable());
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 // We care about the syntactic form of the initializer list, only.
2207 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2208 IE = Syntactic;
2209 EnqueueChildren(IE);
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 WL.push_back(MemberExprParts(M, Parent));
2213
2214 // If the base of the member access expression is an implicit 'this', don't
2215 // visit it.
2216 // FIXME: If we ever want to show these implicit accesses, this will be
2217 // unfortunate. However, clang_getCursor() relies on this behavior.
2218 if (!M->isImplicitAccess())
2219 AddStmt(M->getBase());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddTypeLoc(E->getEncodedTypeSourceInfo());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 EnqueueChildren(M);
2226 AddTypeLoc(M->getClassReceiverTypeInfo());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // Visit the components of the offsetof expression.
2230 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2231 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2232 const OffsetOfNode &Node = E->getComponent(I-1);
2233 switch (Node.getKind()) {
2234 case OffsetOfNode::Array:
2235 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2236 break;
2237 case OffsetOfNode::Field:
2238 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2239 break;
2240 case OffsetOfNode::Identifier:
2241 case OffsetOfNode::Base:
2242 continue;
2243 }
2244 }
2245 // Visit the type into which we're computing the offset.
2246 AddTypeLoc(E->getTypeSourceInfo());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2250 WL.push_back(OverloadExprParts(E, Parent));
2251}
2252void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 if (E->isArgumentType())
2256 AddTypeLoc(E->getArgumentTypeInfo());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 EnqueueChildren(S);
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(S->getBody());
2263 AddStmt(S->getCond());
2264 AddDecl(S->getConditionVariable());
2265}
2266
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddStmt(W->getBody());
2269 AddStmt(W->getCond());
2270 AddDecl(W->getConditionVariable());
2271}
2272
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 for (unsigned I = E->getNumArgs(); I > 0; --I)
2275 AddTypeLoc(E->getArg(I-1));
2276}
2277
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 AddTypeLoc(E->getQueriedTypeSourceInfo());
2280}
2281
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 EnqueueChildren(E);
2284}
2285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 VisitOverloadExpr(U);
2288 if (!U->isImplicitAccess())
2289 AddStmt(U->getBase());
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 AddStmt(E->getSubExpr());
2293 AddTypeLoc(E->getWrittenTypeInfo());
2294}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 WL.push_back(SizeOfPackExprParts(E, Parent));
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 // If the opaque value has a source expression, just transparently
2300 // visit that. This is useful for (e.g.) pseudo-object expressions.
2301 if (Expr *SourceExpr = E->getSourceExpr())
2302 return Visit(SourceExpr);
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 AddStmt(E->getBody());
2306 WL.push_back(LambdaExprParts(E, Parent));
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 // Treat the expression like its syntactic form.
2310 Visit(E->getSyntacticForm());
2311}
2312
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002313void EnqueueVisitor::VisitOMPExecutableDirective(
2314 const OMPExecutableDirective *D) {
2315 EnqueueChildren(D);
2316 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2317 E = D->clauses().end();
2318 I != E; ++I)
2319 EnqueueChildren(*I);
2320}
2321
2322void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2323 VisitOMPExecutableDirective(D);
2324}
2325
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002326void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2327 VisitOMPExecutableDirective(D);
2328}
2329
Alexey Bataevf29276e2014-06-18 04:14:57 +00002330void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2331 VisitOMPExecutableDirective(D);
2332}
2333
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002334void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002338void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2339 VisitOMPExecutableDirective(D);
2340}
2341
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002342void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2343 VisitOMPExecutableDirective(D);
2344}
2345
Alexander Musman80c22892014-07-17 08:54:58 +00002346void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2347 VisitOMPExecutableDirective(D);
2348}
2349
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002350void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2351 VisitOMPExecutableDirective(D);
2352 AddDeclarationNameInfo(D);
2353}
2354
Alexey Bataev4acb8592014-07-07 13:01:15 +00002355void
2356EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358}
2359
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002360void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2361 const OMPParallelSectionsDirective *D) {
2362 VisitOMPExecutableDirective(D);
2363}
2364
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002365void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2366 VisitOMPExecutableDirective(D);
2367}
2368
Alexey Bataev68446b72014-07-18 07:47:19 +00002369void
2370EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2371 VisitOMPExecutableDirective(D);
2372}
2373
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002374void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2375 VisitOMPExecutableDirective(D);
2376}
2377
Alexey Bataev2df347a2014-07-18 10:17:07 +00002378void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2379 VisitOMPExecutableDirective(D);
2380}
2381
Alexey Bataev6125da92014-07-21 11:26:11 +00002382void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2383 VisitOMPExecutableDirective(D);
2384}
2385
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002386void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2387 VisitOMPExecutableDirective(D);
2388}
2389
Alexey Bataev0162e452014-07-22 10:10:35 +00002390void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2391 VisitOMPExecutableDirective(D);
2392}
2393
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2396}
2397
2398bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2399 if (RegionOfInterest.isValid()) {
2400 SourceRange Range = getRawCursorExtent(C);
2401 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2402 return false;
2403 }
2404 return true;
2405}
2406
2407bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2408 while (!WL.empty()) {
2409 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002410 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002411
2412 // Set the Parent field, then back to its old value once we're done.
2413 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2414
2415 switch (LI.getKind()) {
2416 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 if (!D)
2419 continue;
2420
2421 // For now, perform default visitation for Decls.
2422 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2423 cast<DeclVisit>(&LI)->isFirst())))
2424 return true;
2425
2426 continue;
2427 }
2428 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2429 const ASTTemplateArgumentListInfo *ArgList =
2430 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2431 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2432 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2433 Arg != ArgEnd; ++Arg) {
2434 if (VisitTemplateArgumentLoc(*Arg))
2435 return true;
2436 }
2437 continue;
2438 }
2439 case VisitorJob::TypeLocVisitKind: {
2440 // Perform default visitation for TypeLocs.
2441 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2442 return true;
2443 continue;
2444 }
2445 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 if (LabelStmt *stmt = LS->getStmt()) {
2448 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2449 TU))) {
2450 return true;
2451 }
2452 }
2453 continue;
2454 }
2455
2456 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2457 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2458 if (VisitNestedNameSpecifierLoc(V->get()))
2459 return true;
2460 continue;
2461 }
2462
2463 case VisitorJob::DeclarationNameInfoVisitKind: {
2464 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2465 ->get()))
2466 return true;
2467 continue;
2468 }
2469 case VisitorJob::MemberRefVisitKind: {
2470 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2471 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2472 return true;
2473 continue;
2474 }
2475 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 if (!S)
2478 continue;
2479
2480 // Update the current cursor.
2481 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2482 if (!IsInRegionOfInterest(Cursor))
2483 continue;
2484 switch (Visitor(Cursor, Parent, ClientData)) {
2485 case CXChildVisit_Break: return true;
2486 case CXChildVisit_Continue: break;
2487 case CXChildVisit_Recurse:
2488 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002489 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002490 EnqueueWorkList(WL, S);
2491 break;
2492 }
2493 continue;
2494 }
2495 case VisitorJob::MemberExprPartsKind: {
2496 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002498
2499 // Visit the nested-name-specifier
2500 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2501 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2502 return true;
2503
2504 // Visit the declaration name.
2505 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2506 return true;
2507
2508 // Visit the explicitly-specified template arguments, if any.
2509 if (M->hasExplicitTemplateArgs()) {
2510 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2511 *ArgEnd = Arg + M->getNumTemplateArgs();
2512 Arg != ArgEnd; ++Arg) {
2513 if (VisitTemplateArgumentLoc(*Arg))
2514 return true;
2515 }
2516 }
2517 continue;
2518 }
2519 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 // Visit nested-name-specifier, if present.
2522 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2523 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2524 return true;
2525 // Visit declaration name.
2526 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2527 return true;
2528 continue;
2529 }
2530 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 // Visit the nested-name-specifier.
2533 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2534 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2535 return true;
2536 // Visit the declaration name.
2537 if (VisitDeclarationNameInfo(O->getNameInfo()))
2538 return true;
2539 // Visit the overloaded declaration reference.
2540 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2541 return true;
2542 continue;
2543 }
2544 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002545 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 NamedDecl *Pack = E->getPack();
2547 if (isa<TemplateTypeParmDecl>(Pack)) {
2548 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2549 E->getPackLoc(), TU)))
2550 return true;
2551
2552 continue;
2553 }
2554
2555 if (isa<TemplateTemplateParmDecl>(Pack)) {
2556 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2557 E->getPackLoc(), TU)))
2558 return true;
2559
2560 continue;
2561 }
2562
2563 // Non-type template parameter packs and function parameter packs are
2564 // treated like DeclRefExpr cursors.
2565 continue;
2566 }
2567
2568 case VisitorJob::LambdaExprPartsKind: {
2569 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002570 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002571 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2572 CEnd = E->explicit_capture_end();
2573 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002574 // FIXME: Lambda init-captures.
2575 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002576 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002577
Guy Benyei11169dd2012-12-18 14:30:41 +00002578 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2579 C->getLocation(),
2580 TU)))
2581 return true;
2582 }
2583
2584 // Visit parameters and return type, if present.
2585 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2586 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2587 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2588 // Visit the whole type.
2589 if (Visit(TL))
2590 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002591 } else if (FunctionProtoTypeLoc Proto =
2592 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002593 if (E->hasExplicitParameters()) {
2594 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002595 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2596 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002597 return true;
2598 } else {
2599 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002600 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 return true;
2602 }
2603 }
2604 }
2605 break;
2606 }
2607
2608 case VisitorJob::PostChildrenVisitKind:
2609 if (PostChildrenVisitor(Parent, ClientData))
2610 return true;
2611 break;
2612 }
2613 }
2614 return false;
2615}
2616
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002617bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002618 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002619 if (!WorkListFreeList.empty()) {
2620 WL = WorkListFreeList.back();
2621 WL->clear();
2622 WorkListFreeList.pop_back();
2623 }
2624 else {
2625 WL = new VisitorWorkList();
2626 WorkListCache.push_back(WL);
2627 }
2628 EnqueueWorkList(*WL, S);
2629 bool result = RunVisitorWorkList(*WL);
2630 WorkListFreeList.push_back(WL);
2631 return result;
2632}
2633
2634namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002635typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002636RefNamePieces
2637buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2638 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2639 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002640 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2641 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2642 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2643
2644 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2645
2646 RefNamePieces Pieces;
2647
2648 if (WantQualifier && QLoc.isValid())
2649 Pieces.push_back(QLoc);
2650
2651 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2652 Pieces.push_back(NI.getLoc());
2653
2654 if (WantTemplateArgs && TemplateArgs)
2655 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2656 TemplateArgs->RAngleLoc));
2657
2658 if (Kind == DeclarationName::CXXOperatorName) {
2659 Pieces.push_back(SourceLocation::getFromRawEncoding(
2660 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2661 Pieces.push_back(SourceLocation::getFromRawEncoding(
2662 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2663 }
2664
2665 if (WantSinglePiece) {
2666 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2667 Pieces.clear();
2668 Pieces.push_back(R);
2669 }
2670
2671 return Pieces;
2672}
2673}
2674
2675//===----------------------------------------------------------------------===//
2676// Misc. API hooks.
2677//===----------------------------------------------------------------------===//
2678
Chad Rosier05c71aa2013-03-27 18:28:23 +00002679static void fatal_error_handler(void *user_data, const std::string& reason,
2680 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002681 // Write the result out to stderr avoiding errs() because raw_ostreams can
2682 // call report_fatal_error.
2683 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2684 ::abort();
2685}
2686
Chandler Carruth66660742014-06-27 16:37:27 +00002687namespace {
2688struct RegisterFatalErrorHandler {
2689 RegisterFatalErrorHandler() {
2690 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2691 }
2692};
2693}
2694
2695static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2696
Guy Benyei11169dd2012-12-18 14:30:41 +00002697extern "C" {
2698CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2699 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 // We use crash recovery to make some of our APIs more reliable, implicitly
2701 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002702 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2703 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002704
Chandler Carruth66660742014-06-27 16:37:27 +00002705 // Look through the managed static to trigger construction of the managed
2706 // static which registers our fatal error handler. This ensures it is only
2707 // registered once.
2708 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002709
2710 CIndexer *CIdxr = new CIndexer();
2711 if (excludeDeclarationsFromPCH)
2712 CIdxr->setOnlyLocalDecls();
2713 if (displayDiagnostics)
2714 CIdxr->setDisplayDiagnostics();
2715
2716 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2717 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2718 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2719 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2720 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2721 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2722
2723 return CIdxr;
2724}
2725
2726void clang_disposeIndex(CXIndex CIdx) {
2727 if (CIdx)
2728 delete static_cast<CIndexer *>(CIdx);
2729}
2730
2731void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2732 if (CIdx)
2733 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2734}
2735
2736unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2737 if (CIdx)
2738 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2739 return 0;
2740}
2741
2742void clang_toggleCrashRecovery(unsigned isEnabled) {
2743 if (isEnabled)
2744 llvm::CrashRecoveryContext::Enable();
2745 else
2746 llvm::CrashRecoveryContext::Disable();
2747}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002748
Guy Benyei11169dd2012-12-18 14:30:41 +00002749CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2750 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002751 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002752 enum CXErrorCode Result =
2753 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002754 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002755 assert((TU && Result == CXError_Success) ||
2756 (!TU && Result != CXError_Success));
2757 return TU;
2758}
2759
2760enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2761 const char *ast_filename,
2762 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002763 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002764 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002765
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002766 if (!CIdx || !ast_filename || !out_TU)
2767 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002768
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002769 LOG_FUNC_SECTION {
2770 *Log << ast_filename;
2771 }
2772
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2774 FileSystemOptions FileSystemOpts;
2775
2776 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002777 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002778 CXXIdx->getOnlyLocalDecls(), None,
2779 /*CaptureDiagnostics=*/true,
2780 /*AllowPCHWithCompilerErrors=*/true,
2781 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002782 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2783 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002784}
2785
2786unsigned clang_defaultEditingTranslationUnitOptions() {
2787 return CXTranslationUnit_PrecompiledPreamble |
2788 CXTranslationUnit_CacheCompletionResults;
2789}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002790
Guy Benyei11169dd2012-12-18 14:30:41 +00002791CXTranslationUnit
2792clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2793 const char *source_filename,
2794 int num_command_line_args,
2795 const char * const *command_line_args,
2796 unsigned num_unsaved_files,
2797 struct CXUnsavedFile *unsaved_files) {
2798 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2799 return clang_parseTranslationUnit(CIdx, source_filename,
2800 command_line_args, num_command_line_args,
2801 unsaved_files, num_unsaved_files,
2802 Options);
2803}
2804
2805struct ParseTranslationUnitInfo {
2806 CXIndex CIdx;
2807 const char *source_filename;
2808 const char *const *command_line_args;
2809 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002810 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002811 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002812 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002813 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002814};
2815static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002816 const ParseTranslationUnitInfo *PTUI =
2817 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 CXIndex CIdx = PTUI->CIdx;
2819 const char *source_filename = PTUI->source_filename;
2820 const char * const *command_line_args = PTUI->command_line_args;
2821 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002822 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002824
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002825 // Set up the initial return values.
2826 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002827 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002828
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002830 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002831 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833 }
2834
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2836
2837 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2838 setThreadBackgroundPriority();
2839
2840 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2841 // FIXME: Add a flag for modules.
2842 TranslationUnitKind TUKind
2843 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002844 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 = options & CXTranslationUnit_CacheCompletionResults;
2846 bool IncludeBriefCommentsInCodeCompletion
2847 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2848 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2849 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2850
2851 // Configure the diagnostics.
2852 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002853 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002854
2855 // Recover resources if we crash before exiting this function.
2856 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2857 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002858 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002859
Ahmed Charlesb8984322014-03-07 20:03:18 +00002860 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2861 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002862
2863 // Recover resources if we crash before exiting this function.
2864 llvm::CrashRecoveryContextCleanupRegistrar<
2865 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2866
Alp Toker9d85b182014-07-07 01:23:14 +00002867 for (auto &UF : PTUI->unsaved_files) {
2868 llvm::MemoryBuffer *MB =
2869 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2870 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 }
2872
Ahmed Charlesb8984322014-03-07 20:03:18 +00002873 std::unique_ptr<std::vector<const char *>> Args(
2874 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
2876 // Recover resources if we crash before exiting this method.
2877 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2878 ArgsCleanup(Args.get());
2879
2880 // Since the Clang C library is primarily used by batch tools dealing with
2881 // (often very broken) source code, where spell-checking can have a
2882 // significant negative impact on performance (particularly when
2883 // precompiled headers are involved), we disable it by default.
2884 // Only do this if we haven't found a spell-checking-related argument.
2885 bool FoundSpellCheckingArgument = false;
2886 for (int I = 0; I != num_command_line_args; ++I) {
2887 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2888 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2889 FoundSpellCheckingArgument = true;
2890 break;
2891 }
2892 }
2893 if (!FoundSpellCheckingArgument)
2894 Args->push_back("-fno-spell-checking");
2895
2896 Args->insert(Args->end(), command_line_args,
2897 command_line_args + num_command_line_args);
2898
2899 // The 'source_filename' argument is optional. If the caller does not
2900 // specify it then it is assumed that the source file is specified
2901 // in the actual argument list.
2902 // Put the source file after command_line_args otherwise if '-x' flag is
2903 // present it will be unused.
2904 if (source_filename)
2905 Args->push_back(source_filename);
2906
2907 // Do we need the detailed preprocessing record?
2908 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2909 Args->push_back("-Xclang");
2910 Args->push_back("-detailed-preprocessing-record");
2911 }
2912
2913 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002914 std::unique_ptr<ASTUnit> ErrUnit;
2915 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002916 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002917 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2918 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2919 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2920 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2921 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2922 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002923
2924 if (NumErrors != Diags->getClient()->getNumErrors()) {
2925 // Make sure to check that 'Unit' is non-NULL.
2926 if (CXXIdx->getDisplayDiagnostics())
2927 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2928 }
2929
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002930 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2931 PTUI->result = CXError_ASTReadError;
2932 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002933 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002934 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2935 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002936}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002937
2938CXTranslationUnit
2939clang_parseTranslationUnit(CXIndex CIdx,
2940 const char *source_filename,
2941 const char *const *command_line_args,
2942 int num_command_line_args,
2943 struct CXUnsavedFile *unsaved_files,
2944 unsigned num_unsaved_files,
2945 unsigned options) {
2946 CXTranslationUnit TU;
2947 enum CXErrorCode Result = clang_parseTranslationUnit2(
2948 CIdx, source_filename, command_line_args, num_command_line_args,
2949 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002950 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002951 assert((TU && Result == CXError_Success) ||
2952 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953 return TU;
2954}
2955
2956enum CXErrorCode clang_parseTranslationUnit2(
2957 CXIndex CIdx,
2958 const char *source_filename,
2959 const char *const *command_line_args,
2960 int num_command_line_args,
2961 struct CXUnsavedFile *unsaved_files,
2962 unsigned num_unsaved_files,
2963 unsigned options,
2964 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002965 LOG_FUNC_SECTION {
2966 *Log << source_filename << ": ";
2967 for (int i = 0; i != num_command_line_args; ++i)
2968 *Log << command_line_args[i] << " ";
2969 }
2970
Alp Toker9d85b182014-07-07 01:23:14 +00002971 if (num_unsaved_files && !unsaved_files)
2972 return CXError_InvalidArguments;
2973
Alp Toker5c532982014-07-07 22:42:03 +00002974 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002975 ParseTranslationUnitInfo PTUI = {
2976 CIdx,
2977 source_filename,
2978 command_line_args,
2979 num_command_line_args,
2980 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2981 options,
2982 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002983 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 llvm::CrashRecoveryContext CRC;
2985
2986 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2987 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2988 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2989 fprintf(stderr, " 'command_line_args' : [");
2990 for (int i = 0; i != num_command_line_args; ++i) {
2991 if (i)
2992 fprintf(stderr, ", ");
2993 fprintf(stderr, "'%s'", command_line_args[i]);
2994 }
2995 fprintf(stderr, "],\n");
2996 fprintf(stderr, " 'unsaved_files' : [");
2997 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2998 if (i)
2999 fprintf(stderr, ", ");
3000 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3001 unsaved_files[i].Length);
3002 }
3003 fprintf(stderr, "],\n");
3004 fprintf(stderr, " 'options' : %d,\n", options);
3005 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006
3007 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 if (CXTranslationUnit *TU = PTUI.out_TU)
3010 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 }
Alp Toker5c532982014-07-07 22:42:03 +00003012
3013 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003014}
3015
3016unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3017 return CXSaveTranslationUnit_None;
3018}
3019
3020namespace {
3021
3022struct SaveTranslationUnitInfo {
3023 CXTranslationUnit TU;
3024 const char *FileName;
3025 unsigned options;
3026 CXSaveError result;
3027};
3028
3029}
3030
3031static void clang_saveTranslationUnit_Impl(void *UserData) {
3032 SaveTranslationUnitInfo *STUI =
3033 static_cast<SaveTranslationUnitInfo*>(UserData);
3034
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003035 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003036 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3037 setThreadBackgroundPriority();
3038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003039 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3041}
3042
3043int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3044 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003045 LOG_FUNC_SECTION {
3046 *Log << TU << ' ' << FileName;
3047 }
3048
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003050 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003052 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003055 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3056 if (!CXXUnit->hasSema())
3057 return CXSaveError_InvalidTU;
3058
3059 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3060
3061 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3062 getenv("LIBCLANG_NOTHREADS")) {
3063 clang_saveTranslationUnit_Impl(&STUI);
3064
3065 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3066 PrintLibclangResourceUsage(TU);
3067
3068 return STUI.result;
3069 }
3070
3071 // We have an AST that has invalid nodes due to compiler errors.
3072 // Use a crash recovery thread for protection.
3073
3074 llvm::CrashRecoveryContext CRC;
3075
3076 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3077 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3078 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3079 fprintf(stderr, " 'options' : %d,\n", options);
3080 fprintf(stderr, "}\n");
3081
3082 return CXSaveError_Unknown;
3083
3084 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3085 PrintLibclangResourceUsage(TU);
3086 }
3087
3088 return STUI.result;
3089}
3090
3091void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3092 if (CTUnit) {
3093 // If the translation unit has been marked as unsafe to free, just discard
3094 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003095 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3096 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 return;
3098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003099 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003100 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3102 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003103 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 delete CTUnit;
3105 }
3106}
3107
3108unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3109 return CXReparse_None;
3110}
3111
3112struct ReparseTranslationUnitInfo {
3113 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003114 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003116 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003117};
3118
3119static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003120 const ReparseTranslationUnitInfo *RTUI =
3121 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003123 unsigned options = RTUI->options;
3124 (void) options;
3125
3126 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003127 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003129 RTUI->result = CXError_InvalidArguments;
3130 return;
3131 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003132
3133 // Reset the associated diagnostics.
3134 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003135 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003136
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003137 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3139 setThreadBackgroundPriority();
3140
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003141 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003143
3144 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3145 new std::vector<ASTUnit::RemappedFile>());
3146
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 // Recover resources if we crash before exiting this function.
3148 llvm::CrashRecoveryContextCleanupRegistrar<
3149 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003150
3151 for (auto &UF : RTUI->unsaved_files) {
3152 llvm::MemoryBuffer *MB =
3153 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3154 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003156
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003157 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003158 RTUI->result = CXError_Success;
3159 else if (isASTReadError(CXXUnit))
3160 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003161}
3162
3163int clang_reparseTranslationUnit(CXTranslationUnit TU,
3164 unsigned num_unsaved_files,
3165 struct CXUnsavedFile *unsaved_files,
3166 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003167 LOG_FUNC_SECTION {
3168 *Log << TU;
3169 }
3170
Alp Toker9d85b182014-07-07 01:23:14 +00003171 if (num_unsaved_files && !unsaved_files)
3172 return CXError_InvalidArguments;
3173
Alp Toker5c532982014-07-07 22:42:03 +00003174 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003175 ReparseTranslationUnitInfo RTUI = {
3176 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003177 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003178
3179 if (getenv("LIBCLANG_NOTHREADS")) {
3180 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003181 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 }
3183
3184 llvm::CrashRecoveryContext CRC;
3185
3186 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3187 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003188 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003189 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3191 PrintLibclangResourceUsage(TU);
3192
Alp Toker5c532982014-07-07 22:42:03 +00003193 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003194}
3195
3196
3197CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003198 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003199 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003200 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003201 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003202
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003203 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003204 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003205}
3206
3207CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003208 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003209 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003210 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003211 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003212
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003213 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3215}
3216
3217} // end: extern "C"
3218
3219//===----------------------------------------------------------------------===//
3220// CXFile Operations.
3221//===----------------------------------------------------------------------===//
3222
3223extern "C" {
3224CXString clang_getFileName(CXFile SFile) {
3225 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003226 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003227
3228 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003229 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003230}
3231
3232time_t clang_getFileTime(CXFile SFile) {
3233 if (!SFile)
3234 return 0;
3235
3236 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3237 return FEnt->getModificationTime();
3238}
3239
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003240CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003241 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003242 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003243 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003245
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003246 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
3248 FileManager &FMgr = CXXUnit->getFileManager();
3249 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3250}
3251
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003252unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3253 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003254 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003255 LOG_BAD_TU(TU);
3256 return 0;
3257 }
3258
3259 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return 0;
3261
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003262 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 FileEntry *FEnt = static_cast<FileEntry *>(file);
3264 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3265 .isFileMultipleIncludeGuarded(FEnt);
3266}
3267
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003268int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3269 if (!file || !outID)
3270 return 1;
3271
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003272 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003273 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3274 outID->data[0] = ID.getDevice();
3275 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003276 outID->data[2] = FEnt->getModificationTime();
3277 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003278}
3279
Guy Benyei11169dd2012-12-18 14:30:41 +00003280} // end: extern "C"
3281
3282//===----------------------------------------------------------------------===//
3283// CXCursor Operations.
3284//===----------------------------------------------------------------------===//
3285
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286static const Decl *getDeclFromExpr(const Stmt *E) {
3287 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 return getDeclFromExpr(CE->getSubExpr());
3289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 if (PRE->isExplicitProperty())
3298 return PRE->getExplicitProperty();
3299 // It could be messaging both getter and setter as in:
3300 // ++myobj.myprop;
3301 // in which case prefer to associate the setter since it is less obvious
3302 // from inspecting the source that the setter is going to get called.
3303 if (PRE->isMessagingSetter())
3304 return PRE->getImplicitPropertySetter();
3305 return PRE->getImplicitPropertyGetter();
3306 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003307 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003309 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 if (Expr *Src = OVE->getSourceExpr())
3311 return getDeclFromExpr(Src);
3312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (!CE->isElidable())
3317 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 return OME->getMethodDecl();
3320
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003321 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003323 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3325 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003326 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3328 isa<ParmVarDecl>(SizeOfPack->getPack()))
3329 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003330
3331 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332}
3333
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003334static SourceLocation getLocationFromExpr(const Expr *E) {
3335 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 return getLocationFromExpr(CE->getSubExpr());
3337
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003338 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003340 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003342 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003344 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003346 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003348 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 return PropRef->getLocation();
3350
3351 return E->getLocStart();
3352}
3353
3354extern "C" {
3355
3356unsigned clang_visitChildren(CXCursor parent,
3357 CXCursorVisitor visitor,
3358 CXClientData client_data) {
3359 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3360 /*VisitPreprocessorLast=*/false);
3361 return CursorVis.VisitChildren(parent);
3362}
3363
3364#ifndef __has_feature
3365#define __has_feature(x) 0
3366#endif
3367#if __has_feature(blocks)
3368typedef enum CXChildVisitResult
3369 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3370
3371static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3372 CXClientData client_data) {
3373 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3374 return block(cursor, parent);
3375}
3376#else
3377// If we are compiled with a compiler that doesn't have native blocks support,
3378// define and call the block manually, so the
3379typedef struct _CXChildVisitResult
3380{
3381 void *isa;
3382 int flags;
3383 int reserved;
3384 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3385 CXCursor);
3386} *CXCursorVisitorBlock;
3387
3388static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3389 CXClientData client_data) {
3390 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3391 return block->invoke(block, cursor, parent);
3392}
3393#endif
3394
3395
3396unsigned clang_visitChildrenWithBlock(CXCursor parent,
3397 CXCursorVisitorBlock block) {
3398 return clang_visitChildren(parent, visitWithBlock, block);
3399}
3400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003403 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 if (const ObjCPropertyImplDecl *PropImpl =
3408 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003410 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003411
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003412 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003414 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003415
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003416 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003420 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003422 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3424 // and returns different names. NamedDecl returns the class name and
3425 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003426 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
3428 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003429 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003430
3431 SmallString<1024> S;
3432 llvm::raw_svector_ostream os(S);
3433 ND->printName(os);
3434
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003435 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003436}
3437
3438CXString clang_getCursorSpelling(CXCursor C) {
3439 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003440 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
3442 if (clang_isReference(C.kind)) {
3443 switch (C.kind) {
3444 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003445 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003446 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 }
3448 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003449 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003450 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 }
3452 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003453 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003455 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 }
3457 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003458 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003459 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 }
3461 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003462 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 assert(Type && "Missing type decl");
3464
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003465 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 getAsString());
3467 }
3468 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003469 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 assert(Template && "Missing template decl");
3471
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003472 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 }
3474
3475 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003476 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 assert(NS && "Missing namespace decl");
3478
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003479 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481
3482 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003483 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 assert(Field && "Missing member decl");
3485
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003486 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 }
3488
3489 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003490 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 assert(Label && "Missing label");
3492
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003493 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 }
3495
3496 case CXCursor_OverloadedDeclRef: {
3497 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3499 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003501 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003504 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 OverloadedTemplateStorage *Ovl
3506 = Storage.get<OverloadedTemplateStorage*>();
3507 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003508 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003509 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 }
3511
3512 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003513 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 assert(Var && "Missing variable decl");
3515
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003516 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518
3519 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003520 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 }
3522 }
3523
3524 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003525 const Expr *E = getCursorExpr(C);
3526
3527 if (C.kind == CXCursor_ObjCStringLiteral ||
3528 C.kind == CXCursor_StringLiteral) {
3529 const StringLiteral *SLit;
3530 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3531 SLit = OSL->getString();
3532 } else {
3533 SLit = cast<StringLiteral>(E);
3534 }
3535 SmallString<256> Buf;
3536 llvm::raw_svector_ostream OS(Buf);
3537 SLit->outputString(OS);
3538 return cxstring::createDup(OS.str());
3539 }
3540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 if (D)
3543 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003544 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546
3547 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003548 const Stmt *S = getCursorStmt(C);
3549 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003552 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 }
3554
3555 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 ->getNameStart());
3558
3559 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 ->getNameStart());
3562
3563 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003564 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003565
3566 if (clang_isDeclaration(C.kind))
3567 return getDeclSpelling(getCursorDecl(C));
3568
3569 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003570 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003571 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 }
3573
3574 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003575 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003576 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 }
3578
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003579 if (C.kind == CXCursor_PackedAttr) {
3580 return cxstring::createRef("packed");
3581 }
3582
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003583 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003584}
3585
3586CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3587 unsigned pieceIndex,
3588 unsigned options) {
3589 if (clang_Cursor_isNull(C))
3590 return clang_getNullRange();
3591
3592 ASTContext &Ctx = getCursorContext(C);
3593
3594 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003595 const Stmt *S = getCursorStmt(C);
3596 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 if (pieceIndex > 0)
3598 return clang_getNullRange();
3599 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3600 }
3601
3602 return clang_getNullRange();
3603 }
3604
3605 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003606 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3608 if (pieceIndex >= ME->getNumSelectorLocs())
3609 return clang_getNullRange();
3610 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3611 }
3612 }
3613
3614 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3615 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003616 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3618 if (pieceIndex >= MD->getNumSelectorLocs())
3619 return clang_getNullRange();
3620 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3621 }
3622 }
3623
3624 if (C.kind == CXCursor_ObjCCategoryDecl ||
3625 C.kind == CXCursor_ObjCCategoryImplDecl) {
3626 if (pieceIndex > 0)
3627 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003628 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3630 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003631 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3633 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3634 }
3635
3636 if (C.kind == CXCursor_ModuleImportDecl) {
3637 if (pieceIndex > 0)
3638 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003639 if (const ImportDecl *ImportD =
3640 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3642 if (!Locs.empty())
3643 return cxloc::translateSourceRange(Ctx,
3644 SourceRange(Locs.front(), Locs.back()));
3645 }
3646 return clang_getNullRange();
3647 }
3648
3649 // FIXME: A CXCursor_InclusionDirective should give the location of the
3650 // filename, but we don't keep track of this.
3651
3652 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3653 // but we don't keep track of this.
3654
3655 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3656 // but we don't keep track of this.
3657
3658 // Default handling, give the location of the cursor.
3659
3660 if (pieceIndex > 0)
3661 return clang_getNullRange();
3662
3663 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3664 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3665 return cxloc::translateSourceRange(Ctx, Loc);
3666}
3667
3668CXString clang_getCursorDisplayName(CXCursor C) {
3669 if (!clang_isDeclaration(C.kind))
3670 return clang_getCursorSpelling(C);
3671
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003674 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003675
3676 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003677 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 D = FunTmpl->getTemplatedDecl();
3679
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003680 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 SmallString<64> Str;
3682 llvm::raw_svector_ostream OS(Str);
3683 OS << *Function;
3684 if (Function->getPrimaryTemplate())
3685 OS << "<>";
3686 OS << "(";
3687 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3688 if (I)
3689 OS << ", ";
3690 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3691 }
3692
3693 if (Function->isVariadic()) {
3694 if (Function->getNumParams())
3695 OS << ", ";
3696 OS << "...";
3697 }
3698 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003699 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 }
3701
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003702 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 SmallString<64> Str;
3704 llvm::raw_svector_ostream OS(Str);
3705 OS << *ClassTemplate;
3706 OS << "<";
3707 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3708 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3709 if (I)
3710 OS << ", ";
3711
3712 NamedDecl *Param = Params->getParam(I);
3713 if (Param->getIdentifier()) {
3714 OS << Param->getIdentifier()->getName();
3715 continue;
3716 }
3717
3718 // There is no parameter name, which makes this tricky. Try to come up
3719 // with something useful that isn't too long.
3720 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3721 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3722 else if (NonTypeTemplateParmDecl *NTTP
3723 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3724 OS << NTTP->getType().getAsString(Policy);
3725 else
3726 OS << "template<...> class";
3727 }
3728
3729 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003730 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 }
3732
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003733 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3735 // If the type was explicitly written, use that.
3736 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003737 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003738
Benjamin Kramer9170e912013-02-22 15:46:01 +00003739 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 llvm::raw_svector_ostream OS(Str);
3741 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003742 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 ClassSpec->getTemplateArgs().data(),
3744 ClassSpec->getTemplateArgs().size(),
3745 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003746 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 }
3748
3749 return clang_getCursorSpelling(C);
3750}
3751
3752CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3753 switch (Kind) {
3754 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003882 case CXCursor_ObjCSelfExpr:
3883 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003972 case CXCursor_SEHLeaveStmt:
3973 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004002 case CXCursor_PackedAttr:
4003 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004004 case CXCursor_PureAttr:
4005 return cxstring::createRef("attribute(pure)");
4006 case CXCursor_ConstAttr:
4007 return cxstring::createRef("attribute(const)");
4008 case CXCursor_NoDuplicateAttr:
4009 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004010 case CXCursor_CUDAConstantAttr:
4011 return cxstring::createRef("attribute(constant)");
4012 case CXCursor_CUDADeviceAttr:
4013 return cxstring::createRef("attribute(device)");
4014 case CXCursor_CUDAGlobalAttr:
4015 return cxstring::createRef("attribute(global)");
4016 case CXCursor_CUDAHostAttr:
4017 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004066 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004067 return cxstring::createRef("OMPParallelDirective");
4068 case CXCursor_OMPSimdDirective:
4069 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004070 case CXCursor_OMPForDirective:
4071 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004072 case CXCursor_OMPSectionsDirective:
4073 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004074 case CXCursor_OMPSectionDirective:
4075 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004076 case CXCursor_OMPSingleDirective:
4077 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004078 case CXCursor_OMPMasterDirective:
4079 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004080 case CXCursor_OMPCriticalDirective:
4081 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004082 case CXCursor_OMPParallelForDirective:
4083 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004084 case CXCursor_OMPParallelSectionsDirective:
4085 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004086 case CXCursor_OMPTaskDirective:
4087 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004088 case CXCursor_OMPTaskyieldDirective:
4089 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004090 case CXCursor_OMPBarrierDirective:
4091 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004092 case CXCursor_OMPTaskwaitDirective:
4093 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004094 case CXCursor_OMPFlushDirective:
4095 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004096 case CXCursor_OMPOrderedDirective:
4097 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004098 case CXCursor_OMPAtomicDirective:
4099 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 }
4101
4102 llvm_unreachable("Unhandled CXCursorKind");
4103}
4104
4105struct GetCursorData {
4106 SourceLocation TokenBeginLoc;
4107 bool PointsAtMacroArgExpansion;
4108 bool VisitedObjCPropertyImplDecl;
4109 SourceLocation VisitedDeclaratorDeclStartLoc;
4110 CXCursor &BestCursor;
4111
4112 GetCursorData(SourceManager &SM,
4113 SourceLocation tokenBegin, CXCursor &outputCursor)
4114 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4115 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4116 VisitedObjCPropertyImplDecl = false;
4117 }
4118};
4119
4120static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4121 CXCursor parent,
4122 CXClientData client_data) {
4123 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4124 CXCursor *BestCursor = &Data->BestCursor;
4125
4126 // If we point inside a macro argument we should provide info of what the
4127 // token is so use the actual cursor, don't replace it with a macro expansion
4128 // cursor.
4129 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4130 return CXChildVisit_Recurse;
4131
4132 if (clang_isDeclaration(cursor.kind)) {
4133 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004134 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4136 if (MD->isImplicit())
4137 return CXChildVisit_Break;
4138
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004139 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4141 // Check that when we have multiple @class references in the same line,
4142 // that later ones do not override the previous ones.
4143 // If we have:
4144 // @class Foo, Bar;
4145 // source ranges for both start at '@', so 'Bar' will end up overriding
4146 // 'Foo' even though the cursor location was at 'Foo'.
4147 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4148 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004149 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4151 if (PrevID != ID &&
4152 !PrevID->isThisDeclarationADefinition() &&
4153 !ID->isThisDeclarationADefinition())
4154 return CXChildVisit_Break;
4155 }
4156
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004157 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4159 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4160 // Check that when we have multiple declarators in the same line,
4161 // that later ones do not override the previous ones.
4162 // If we have:
4163 // int Foo, Bar;
4164 // source ranges for both start at 'int', so 'Bar' will end up overriding
4165 // 'Foo' even though the cursor location was at 'Foo'.
4166 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4167 return CXChildVisit_Break;
4168 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4169
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004170 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4172 (void)PropImp;
4173 // Check that when we have multiple @synthesize in the same line,
4174 // that later ones do not override the previous ones.
4175 // If we have:
4176 // @synthesize Foo, Bar;
4177 // source ranges for both start at '@', so 'Bar' will end up overriding
4178 // 'Foo' even though the cursor location was at 'Foo'.
4179 if (Data->VisitedObjCPropertyImplDecl)
4180 return CXChildVisit_Break;
4181 Data->VisitedObjCPropertyImplDecl = true;
4182 }
4183 }
4184
4185 if (clang_isExpression(cursor.kind) &&
4186 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004187 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 // Avoid having the cursor of an expression replace the declaration cursor
4189 // when the expression source range overlaps the declaration range.
4190 // This can happen for C++ constructor expressions whose range generally
4191 // include the variable declaration, e.g.:
4192 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4193 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4194 D->getLocation() == Data->TokenBeginLoc)
4195 return CXChildVisit_Break;
4196 }
4197 }
4198
4199 // If our current best cursor is the construction of a temporary object,
4200 // don't replace that cursor with a type reference, because we want
4201 // clang_getCursor() to point at the constructor.
4202 if (clang_isExpression(BestCursor->kind) &&
4203 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4204 cursor.kind == CXCursor_TypeRef) {
4205 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4206 // as having the actual point on the type reference.
4207 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4208 return CXChildVisit_Recurse;
4209 }
4210
4211 *BestCursor = cursor;
4212 return CXChildVisit_Recurse;
4213}
4214
4215CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004216 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004217 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004219 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4223
4224 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4225 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4226
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004227 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 CXFile SearchFile;
4229 unsigned SearchLine, SearchColumn;
4230 CXFile ResultFile;
4231 unsigned ResultLine, ResultColumn;
4232 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4233 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4234 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004235
4236 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4237 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004238 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004239 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 SearchFileName = clang_getFileName(SearchFile);
4241 ResultFileName = clang_getFileName(ResultFile);
4242 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4243 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004244 *Log << llvm::format("(%s:%d:%d) = %s",
4245 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4246 clang_getCString(KindSpelling))
4247 << llvm::format("(%s:%d:%d):%s%s",
4248 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4249 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 clang_disposeString(SearchFileName);
4251 clang_disposeString(ResultFileName);
4252 clang_disposeString(KindSpelling);
4253 clang_disposeString(USR);
4254
4255 CXCursor Definition = clang_getCursorDefinition(Result);
4256 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4257 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4258 CXString DefinitionKindSpelling
4259 = clang_getCursorKindSpelling(Definition.kind);
4260 CXFile DefinitionFile;
4261 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004262 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004263 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004265 *Log << llvm::format(" -> %s(%s:%d:%d)",
4266 clang_getCString(DefinitionKindSpelling),
4267 clang_getCString(DefinitionFileName),
4268 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 clang_disposeString(DefinitionFileName);
4270 clang_disposeString(DefinitionKindSpelling);
4271 }
4272 }
4273
4274 return Result;
4275}
4276
4277CXCursor clang_getNullCursor(void) {
4278 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4279}
4280
4281unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004282 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4283 // can't set consistently. For example, when visiting a DeclStmt we will set
4284 // it but we don't set it on the result of clang_getCursorDefinition for
4285 // a reference of the same declaration.
4286 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4287 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4288 // to provide that kind of info.
4289 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004290 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004291 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004292 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004293
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 return X == Y;
4295}
4296
4297unsigned clang_hashCursor(CXCursor C) {
4298 unsigned Index = 0;
4299 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4300 Index = 1;
4301
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004302 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 std::make_pair(C.kind, C.data[Index]));
4304}
4305
4306unsigned clang_isInvalid(enum CXCursorKind K) {
4307 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4308}
4309
4310unsigned clang_isDeclaration(enum CXCursorKind K) {
4311 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4312 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4313}
4314
4315unsigned clang_isReference(enum CXCursorKind K) {
4316 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4317}
4318
4319unsigned clang_isExpression(enum CXCursorKind K) {
4320 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4321}
4322
4323unsigned clang_isStatement(enum CXCursorKind K) {
4324 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4325}
4326
4327unsigned clang_isAttribute(enum CXCursorKind K) {
4328 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4329}
4330
4331unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4332 return K == CXCursor_TranslationUnit;
4333}
4334
4335unsigned clang_isPreprocessing(enum CXCursorKind K) {
4336 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4337}
4338
4339unsigned clang_isUnexposed(enum CXCursorKind K) {
4340 switch (K) {
4341 case CXCursor_UnexposedDecl:
4342 case CXCursor_UnexposedExpr:
4343 case CXCursor_UnexposedStmt:
4344 case CXCursor_UnexposedAttr:
4345 return true;
4346 default:
4347 return false;
4348 }
4349}
4350
4351CXCursorKind clang_getCursorKind(CXCursor C) {
4352 return C.kind;
4353}
4354
4355CXSourceLocation clang_getCursorLocation(CXCursor C) {
4356 if (clang_isReference(C.kind)) {
4357 switch (C.kind) {
4358 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004359 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 = getCursorObjCSuperClassRef(C);
4361 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4362 }
4363
4364 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004365 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 = getCursorObjCProtocolRef(C);
4367 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4368 }
4369
4370 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004371 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 = getCursorObjCClassRef(C);
4373 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4374 }
4375
4376 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004377 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4379 }
4380
4381 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004382 std::pair<const TemplateDecl *, SourceLocation> P =
4383 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4385 }
4386
4387 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004388 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4390 }
4391
4392 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004393 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4395 }
4396
4397 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004398 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4400 }
4401
4402 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004403 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 if (!BaseSpec)
4405 return clang_getNullLocation();
4406
4407 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4408 return cxloc::translateSourceLocation(getCursorContext(C),
4409 TSInfo->getTypeLoc().getBeginLoc());
4410
4411 return cxloc::translateSourceLocation(getCursorContext(C),
4412 BaseSpec->getLocStart());
4413 }
4414
4415 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004416 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4418 }
4419
4420 case CXCursor_OverloadedDeclRef:
4421 return cxloc::translateSourceLocation(getCursorContext(C),
4422 getCursorOverloadedDeclRef(C).second);
4423
4424 default:
4425 // FIXME: Need a way to enumerate all non-reference cases.
4426 llvm_unreachable("Missed a reference kind");
4427 }
4428 }
4429
4430 if (clang_isExpression(C.kind))
4431 return cxloc::translateSourceLocation(getCursorContext(C),
4432 getLocationFromExpr(getCursorExpr(C)));
4433
4434 if (clang_isStatement(C.kind))
4435 return cxloc::translateSourceLocation(getCursorContext(C),
4436 getCursorStmt(C)->getLocStart());
4437
4438 if (C.kind == CXCursor_PreprocessingDirective) {
4439 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4440 return cxloc::translateSourceLocation(getCursorContext(C), L);
4441 }
4442
4443 if (C.kind == CXCursor_MacroExpansion) {
4444 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004445 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 return cxloc::translateSourceLocation(getCursorContext(C), L);
4447 }
4448
4449 if (C.kind == CXCursor_MacroDefinition) {
4450 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4451 return cxloc::translateSourceLocation(getCursorContext(C), L);
4452 }
4453
4454 if (C.kind == CXCursor_InclusionDirective) {
4455 SourceLocation L
4456 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4457 return cxloc::translateSourceLocation(getCursorContext(C), L);
4458 }
4459
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004460 if (clang_isAttribute(C.kind)) {
4461 SourceLocation L
4462 = cxcursor::getCursorAttr(C)->getLocation();
4463 return cxloc::translateSourceLocation(getCursorContext(C), L);
4464 }
4465
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 if (!clang_isDeclaration(C.kind))
4467 return clang_getNullLocation();
4468
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004469 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 if (!D)
4471 return clang_getNullLocation();
4472
4473 SourceLocation Loc = D->getLocation();
4474 // FIXME: Multiple variables declared in a single declaration
4475 // currently lack the information needed to correctly determine their
4476 // ranges when accounting for the type-specifier. We use context
4477 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4478 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004479 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 if (!cxcursor::isFirstInDeclGroup(C))
4481 Loc = VD->getLocation();
4482 }
4483
4484 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004485 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 Loc = MD->getSelectorStartLoc();
4487
4488 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4489}
4490
4491} // end extern "C"
4492
4493CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4494 assert(TU);
4495
4496 // Guard against an invalid SourceLocation, or we may assert in one
4497 // of the following calls.
4498 if (SLoc.isInvalid())
4499 return clang_getNullCursor();
4500
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004501 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004502
4503 // Translate the given source location to make it point at the beginning of
4504 // the token under the cursor.
4505 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4506 CXXUnit->getASTContext().getLangOpts());
4507
4508 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4509 if (SLoc.isValid()) {
4510 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4511 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4512 /*VisitPreprocessorLast=*/true,
4513 /*VisitIncludedEntities=*/false,
4514 SourceLocation(SLoc));
4515 CursorVis.visitFileRegion();
4516 }
4517
4518 return Result;
4519}
4520
4521static SourceRange getRawCursorExtent(CXCursor C) {
4522 if (clang_isReference(C.kind)) {
4523 switch (C.kind) {
4524 case CXCursor_ObjCSuperClassRef:
4525 return getCursorObjCSuperClassRef(C).second;
4526
4527 case CXCursor_ObjCProtocolRef:
4528 return getCursorObjCProtocolRef(C).second;
4529
4530 case CXCursor_ObjCClassRef:
4531 return getCursorObjCClassRef(C).second;
4532
4533 case CXCursor_TypeRef:
4534 return getCursorTypeRef(C).second;
4535
4536 case CXCursor_TemplateRef:
4537 return getCursorTemplateRef(C).second;
4538
4539 case CXCursor_NamespaceRef:
4540 return getCursorNamespaceRef(C).second;
4541
4542 case CXCursor_MemberRef:
4543 return getCursorMemberRef(C).second;
4544
4545 case CXCursor_CXXBaseSpecifier:
4546 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4547
4548 case CXCursor_LabelRef:
4549 return getCursorLabelRef(C).second;
4550
4551 case CXCursor_OverloadedDeclRef:
4552 return getCursorOverloadedDeclRef(C).second;
4553
4554 case CXCursor_VariableRef:
4555 return getCursorVariableRef(C).second;
4556
4557 default:
4558 // FIXME: Need a way to enumerate all non-reference cases.
4559 llvm_unreachable("Missed a reference kind");
4560 }
4561 }
4562
4563 if (clang_isExpression(C.kind))
4564 return getCursorExpr(C)->getSourceRange();
4565
4566 if (clang_isStatement(C.kind))
4567 return getCursorStmt(C)->getSourceRange();
4568
4569 if (clang_isAttribute(C.kind))
4570 return getCursorAttr(C)->getRange();
4571
4572 if (C.kind == CXCursor_PreprocessingDirective)
4573 return cxcursor::getCursorPreprocessingDirective(C);
4574
4575 if (C.kind == CXCursor_MacroExpansion) {
4576 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004577 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 return TU->mapRangeFromPreamble(Range);
4579 }
4580
4581 if (C.kind == CXCursor_MacroDefinition) {
4582 ASTUnit *TU = getCursorASTUnit(C);
4583 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4584 return TU->mapRangeFromPreamble(Range);
4585 }
4586
4587 if (C.kind == CXCursor_InclusionDirective) {
4588 ASTUnit *TU = getCursorASTUnit(C);
4589 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4590 return TU->mapRangeFromPreamble(Range);
4591 }
4592
4593 if (C.kind == CXCursor_TranslationUnit) {
4594 ASTUnit *TU = getCursorASTUnit(C);
4595 FileID MainID = TU->getSourceManager().getMainFileID();
4596 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4597 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4598 return SourceRange(Start, End);
4599 }
4600
4601 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004602 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 if (!D)
4604 return SourceRange();
4605
4606 SourceRange R = D->getSourceRange();
4607 // FIXME: Multiple variables declared in a single declaration
4608 // currently lack the information needed to correctly determine their
4609 // ranges when accounting for the type-specifier. We use context
4610 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4611 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004612 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 if (!cxcursor::isFirstInDeclGroup(C))
4614 R.setBegin(VD->getLocation());
4615 }
4616 return R;
4617 }
4618 return SourceRange();
4619}
4620
4621/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4622/// the decl-specifier-seq for declarations.
4623static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4624 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004625 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 if (!D)
4627 return SourceRange();
4628
4629 SourceRange R = D->getSourceRange();
4630
4631 // Adjust the start of the location for declarations preceded by
4632 // declaration specifiers.
4633 SourceLocation StartLoc;
4634 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4635 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4636 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004637 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4639 StartLoc = TI->getTypeLoc().getLocStart();
4640 }
4641
4642 if (StartLoc.isValid() && R.getBegin().isValid() &&
4643 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4644 R.setBegin(StartLoc);
4645
4646 // FIXME: Multiple variables declared in a single declaration
4647 // currently lack the information needed to correctly determine their
4648 // ranges when accounting for the type-specifier. We use context
4649 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4650 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004651 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 if (!cxcursor::isFirstInDeclGroup(C))
4653 R.setBegin(VD->getLocation());
4654 }
4655
4656 return R;
4657 }
4658
4659 return getRawCursorExtent(C);
4660}
4661
4662extern "C" {
4663
4664CXSourceRange clang_getCursorExtent(CXCursor C) {
4665 SourceRange R = getRawCursorExtent(C);
4666 if (R.isInvalid())
4667 return clang_getNullRange();
4668
4669 return cxloc::translateSourceRange(getCursorContext(C), R);
4670}
4671
4672CXCursor clang_getCursorReferenced(CXCursor C) {
4673 if (clang_isInvalid(C.kind))
4674 return clang_getNullCursor();
4675
4676 CXTranslationUnit tu = getCursorTU(C);
4677 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004678 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 if (!D)
4680 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004681 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 if (const ObjCPropertyImplDecl *PropImpl =
4684 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4686 return MakeCXCursor(Property, tu);
4687
4688 return C;
4689 }
4690
4691 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004692 const Expr *E = getCursorExpr(C);
4693 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 if (D) {
4695 CXCursor declCursor = MakeCXCursor(D, tu);
4696 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4697 declCursor);
4698 return declCursor;
4699 }
4700
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004701 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return MakeCursorOverloadedDeclRef(Ovl, tu);
4703
4704 return clang_getNullCursor();
4705 }
4706
4707 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004708 const Stmt *S = getCursorStmt(C);
4709 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 if (LabelDecl *label = Goto->getLabel())
4711 if (LabelStmt *labelS = label->getStmt())
4712 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4713
4714 return clang_getNullCursor();
4715 }
4716
4717 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004718 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 return MakeMacroDefinitionCursor(Def, tu);
4720 }
4721
4722 if (!clang_isReference(C.kind))
4723 return clang_getNullCursor();
4724
4725 switch (C.kind) {
4726 case CXCursor_ObjCSuperClassRef:
4727 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4728
4729 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004730 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4731 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 return MakeCXCursor(Def, tu);
4733
4734 return MakeCXCursor(Prot, tu);
4735 }
4736
4737 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004738 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4739 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 return MakeCXCursor(Def, tu);
4741
4742 return MakeCXCursor(Class, tu);
4743 }
4744
4745 case CXCursor_TypeRef:
4746 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4747
4748 case CXCursor_TemplateRef:
4749 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4750
4751 case CXCursor_NamespaceRef:
4752 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4753
4754 case CXCursor_MemberRef:
4755 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4756
4757 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004758 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4760 tu ));
4761 }
4762
4763 case CXCursor_LabelRef:
4764 // FIXME: We end up faking the "parent" declaration here because we
4765 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004766 return MakeCXCursor(getCursorLabelRef(C).first,
4767 cxtu::getASTUnit(tu)->getASTContext()
4768 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 tu);
4770
4771 case CXCursor_OverloadedDeclRef:
4772 return C;
4773
4774 case CXCursor_VariableRef:
4775 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4776
4777 default:
4778 // We would prefer to enumerate all non-reference cursor kinds here.
4779 llvm_unreachable("Unhandled reference cursor kind");
4780 }
4781}
4782
4783CXCursor clang_getCursorDefinition(CXCursor C) {
4784 if (clang_isInvalid(C.kind))
4785 return clang_getNullCursor();
4786
4787 CXTranslationUnit TU = getCursorTU(C);
4788
4789 bool WasReference = false;
4790 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4791 C = clang_getCursorReferenced(C);
4792 WasReference = true;
4793 }
4794
4795 if (C.kind == CXCursor_MacroExpansion)
4796 return clang_getCursorReferenced(C);
4797
4798 if (!clang_isDeclaration(C.kind))
4799 return clang_getNullCursor();
4800
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004801 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004802 if (!D)
4803 return clang_getNullCursor();
4804
4805 switch (D->getKind()) {
4806 // Declaration kinds that don't really separate the notions of
4807 // declaration and definition.
4808 case Decl::Namespace:
4809 case Decl::Typedef:
4810 case Decl::TypeAlias:
4811 case Decl::TypeAliasTemplate:
4812 case Decl::TemplateTypeParm:
4813 case Decl::EnumConstant:
4814 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004815 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 case Decl::IndirectField:
4817 case Decl::ObjCIvar:
4818 case Decl::ObjCAtDefsField:
4819 case Decl::ImplicitParam:
4820 case Decl::ParmVar:
4821 case Decl::NonTypeTemplateParm:
4822 case Decl::TemplateTemplateParm:
4823 case Decl::ObjCCategoryImpl:
4824 case Decl::ObjCImplementation:
4825 case Decl::AccessSpec:
4826 case Decl::LinkageSpec:
4827 case Decl::ObjCPropertyImpl:
4828 case Decl::FileScopeAsm:
4829 case Decl::StaticAssert:
4830 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004831 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 case Decl::Label: // FIXME: Is this right??
4833 case Decl::ClassScopeFunctionSpecialization:
4834 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004835 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 return C;
4837
4838 // Declaration kinds that don't make any sense here, but are
4839 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004840 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 case Decl::TranslationUnit:
4842 break;
4843
4844 // Declaration kinds for which the definition is not resolvable.
4845 case Decl::UnresolvedUsingTypename:
4846 case Decl::UnresolvedUsingValue:
4847 break;
4848
4849 case Decl::UsingDirective:
4850 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4851 TU);
4852
4853 case Decl::NamespaceAlias:
4854 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4855
4856 case Decl::Enum:
4857 case Decl::Record:
4858 case Decl::CXXRecord:
4859 case Decl::ClassTemplateSpecialization:
4860 case Decl::ClassTemplatePartialSpecialization:
4861 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4862 return MakeCXCursor(Def, TU);
4863 return clang_getNullCursor();
4864
4865 case Decl::Function:
4866 case Decl::CXXMethod:
4867 case Decl::CXXConstructor:
4868 case Decl::CXXDestructor:
4869 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004870 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004872 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 return clang_getNullCursor();
4874 }
4875
Larisse Voufo39a1e502013-08-06 01:03:05 +00004876 case Decl::Var:
4877 case Decl::VarTemplateSpecialization:
4878 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004880 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 return MakeCXCursor(Def, TU);
4882 return clang_getNullCursor();
4883 }
4884
4885 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004886 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4888 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4889 return clang_getNullCursor();
4890 }
4891
4892 case Decl::ClassTemplate: {
4893 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4894 ->getDefinition())
4895 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4896 TU);
4897 return clang_getNullCursor();
4898 }
4899
Larisse Voufo39a1e502013-08-06 01:03:05 +00004900 case Decl::VarTemplate: {
4901 if (VarDecl *Def =
4902 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4903 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4904 return clang_getNullCursor();
4905 }
4906
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 case Decl::Using:
4908 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4909 D->getLocation(), TU);
4910
4911 case Decl::UsingShadow:
4912 return clang_getCursorDefinition(
4913 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4914 TU));
4915
4916 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004917 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 if (Method->isThisDeclarationADefinition())
4919 return C;
4920
4921 // Dig out the method definition in the associated
4922 // @implementation, if we have it.
4923 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004924 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4926 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4927 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4928 Method->isInstanceMethod()))
4929 if (Def->isThisDeclarationADefinition())
4930 return MakeCXCursor(Def, TU);
4931
4932 return clang_getNullCursor();
4933 }
4934
4935 case Decl::ObjCCategory:
4936 if (ObjCCategoryImplDecl *Impl
4937 = cast<ObjCCategoryDecl>(D)->getImplementation())
4938 return MakeCXCursor(Impl, TU);
4939 return clang_getNullCursor();
4940
4941 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 return MakeCXCursor(Def, TU);
4944 return clang_getNullCursor();
4945
4946 case Decl::ObjCInterface: {
4947 // There are two notions of a "definition" for an Objective-C
4948 // class: the interface and its implementation. When we resolved a
4949 // reference to an Objective-C class, produce the @interface as
4950 // the definition; when we were provided with the interface,
4951 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 return MakeCXCursor(Def, TU);
4956 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4957 return MakeCXCursor(Impl, TU);
4958 return clang_getNullCursor();
4959 }
4960
4961 case Decl::ObjCProperty:
4962 // FIXME: We don't really know where to find the
4963 // ObjCPropertyImplDecls that implement this property.
4964 return clang_getNullCursor();
4965
4966 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004967 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 return MakeCXCursor(Def, TU);
4971
4972 return clang_getNullCursor();
4973
4974 case Decl::Friend:
4975 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4976 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4977 return clang_getNullCursor();
4978
4979 case Decl::FriendTemplate:
4980 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4981 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4982 return clang_getNullCursor();
4983 }
4984
4985 return clang_getNullCursor();
4986}
4987
4988unsigned clang_isCursorDefinition(CXCursor C) {
4989 if (!clang_isDeclaration(C.kind))
4990 return 0;
4991
4992 return clang_getCursorDefinition(C) == C;
4993}
4994
4995CXCursor clang_getCanonicalCursor(CXCursor C) {
4996 if (!clang_isDeclaration(C.kind))
4997 return C;
4998
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004999 if (const Decl *D = getCursorDecl(C)) {
5000 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5002 return MakeCXCursor(CatD, getCursorTU(C));
5003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5005 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 return MakeCXCursor(IFD, getCursorTU(C));
5007
5008 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5009 }
5010
5011 return C;
5012}
5013
5014int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5015 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5016}
5017
5018unsigned clang_getNumOverloadedDecls(CXCursor C) {
5019 if (C.kind != CXCursor_OverloadedDeclRef)
5020 return 0;
5021
5022 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005023 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 return E->getNumDecls();
5025
5026 if (OverloadedTemplateStorage *S
5027 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5028 return S->size();
5029
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005030 const Decl *D = Storage.get<const Decl *>();
5031 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 return Using->shadow_size();
5033
5034 return 0;
5035}
5036
5037CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5038 if (cursor.kind != CXCursor_OverloadedDeclRef)
5039 return clang_getNullCursor();
5040
5041 if (index >= clang_getNumOverloadedDecls(cursor))
5042 return clang_getNullCursor();
5043
5044 CXTranslationUnit TU = getCursorTU(cursor);
5045 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005046 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 return MakeCXCursor(E->decls_begin()[index], TU);
5048
5049 if (OverloadedTemplateStorage *S
5050 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5051 return MakeCXCursor(S->begin()[index], TU);
5052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005053 const Decl *D = Storage.get<const Decl *>();
5054 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 // FIXME: This is, unfortunately, linear time.
5056 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5057 std::advance(Pos, index);
5058 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5059 }
5060
5061 return clang_getNullCursor();
5062}
5063
5064void clang_getDefinitionSpellingAndExtent(CXCursor C,
5065 const char **startBuf,
5066 const char **endBuf,
5067 unsigned *startLine,
5068 unsigned *startColumn,
5069 unsigned *endLine,
5070 unsigned *endColumn) {
5071 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005072 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5074
5075 SourceManager &SM = FD->getASTContext().getSourceManager();
5076 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5077 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5078 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5079 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5080 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5081 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5082}
5083
5084
5085CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5086 unsigned PieceIndex) {
5087 RefNamePieces Pieces;
5088
5089 switch (C.kind) {
5090 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005091 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5093 E->getQualifierLoc().getSourceRange());
5094 break;
5095
5096 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005097 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5099 E->getQualifierLoc().getSourceRange(),
5100 E->getOptionalExplicitTemplateArgs());
5101 break;
5102
5103 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005104 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005106 const Expr *Callee = OCE->getCallee();
5107 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 Callee = ICE->getSubExpr();
5109
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005110 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5112 DRE->getQualifierLoc().getSourceRange());
5113 }
5114 break;
5115
5116 default:
5117 break;
5118 }
5119
5120 if (Pieces.empty()) {
5121 if (PieceIndex == 0)
5122 return clang_getCursorExtent(C);
5123 } else if (PieceIndex < Pieces.size()) {
5124 SourceRange R = Pieces[PieceIndex];
5125 if (R.isValid())
5126 return cxloc::translateSourceRange(getCursorContext(C), R);
5127 }
5128
5129 return clang_getNullRange();
5130}
5131
5132void clang_enableStackTraces(void) {
5133 llvm::sys::PrintStackTraceOnErrorSignal();
5134}
5135
5136void clang_executeOnThread(void (*fn)(void*), void *user_data,
5137 unsigned stack_size) {
5138 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5139}
5140
5141} // end: extern "C"
5142
5143//===----------------------------------------------------------------------===//
5144// Token-based Operations.
5145//===----------------------------------------------------------------------===//
5146
5147/* CXToken layout:
5148 * int_data[0]: a CXTokenKind
5149 * int_data[1]: starting token location
5150 * int_data[2]: token length
5151 * int_data[3]: reserved
5152 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5153 * otherwise unused.
5154 */
5155extern "C" {
5156
5157CXTokenKind clang_getTokenKind(CXToken CXTok) {
5158 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5159}
5160
5161CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5162 switch (clang_getTokenKind(CXTok)) {
5163 case CXToken_Identifier:
5164 case CXToken_Keyword:
5165 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005166 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 ->getNameStart());
5168
5169 case CXToken_Literal: {
5170 // We have stashed the starting pointer in the ptr_data field. Use it.
5171 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005172 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 }
5174
5175 case CXToken_Punctuation:
5176 case CXToken_Comment:
5177 break;
5178 }
5179
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005180 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005181 LOG_BAD_TU(TU);
5182 return cxstring::createEmpty();
5183 }
5184
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 // We have to find the starting buffer pointer the hard way, by
5186 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005187 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005189 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005190
5191 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5192 std::pair<FileID, unsigned> LocInfo
5193 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5194 bool Invalid = false;
5195 StringRef Buffer
5196 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5197 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005198 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005199
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005200 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005201}
5202
5203CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005204 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005205 LOG_BAD_TU(TU);
5206 return clang_getNullLocation();
5207 }
5208
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005209 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 if (!CXXUnit)
5211 return clang_getNullLocation();
5212
5213 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5214 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5215}
5216
5217CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005218 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005219 LOG_BAD_TU(TU);
5220 return clang_getNullRange();
5221 }
5222
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005223 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 if (!CXXUnit)
5225 return clang_getNullRange();
5226
5227 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5228 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5229}
5230
5231static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5232 SmallVectorImpl<CXToken> &CXTokens) {
5233 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5234 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005235 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005237 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005238
5239 // Cannot tokenize across files.
5240 if (BeginLocInfo.first != EndLocInfo.first)
5241 return;
5242
5243 // Create a lexer
5244 bool Invalid = false;
5245 StringRef Buffer
5246 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5247 if (Invalid)
5248 return;
5249
5250 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5251 CXXUnit->getASTContext().getLangOpts(),
5252 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5253 Lex.SetCommentRetentionState(true);
5254
5255 // Lex tokens until we hit the end of the range.
5256 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5257 Token Tok;
5258 bool previousWasAt = false;
5259 do {
5260 // Lex the next token
5261 Lex.LexFromRawLexer(Tok);
5262 if (Tok.is(tok::eof))
5263 break;
5264
5265 // Initialize the CXToken.
5266 CXToken CXTok;
5267
5268 // - Common fields
5269 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5270 CXTok.int_data[2] = Tok.getLength();
5271 CXTok.int_data[3] = 0;
5272
5273 // - Kind-specific fields
5274 if (Tok.isLiteral()) {
5275 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005276 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 } else if (Tok.is(tok::raw_identifier)) {
5278 // Lookup the identifier to determine whether we have a keyword.
5279 IdentifierInfo *II
5280 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5281
5282 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5283 CXTok.int_data[0] = CXToken_Keyword;
5284 }
5285 else {
5286 CXTok.int_data[0] = Tok.is(tok::identifier)
5287 ? CXToken_Identifier
5288 : CXToken_Keyword;
5289 }
5290 CXTok.ptr_data = II;
5291 } else if (Tok.is(tok::comment)) {
5292 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005293 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 } else {
5295 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005296 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 }
5298 CXTokens.push_back(CXTok);
5299 previousWasAt = Tok.is(tok::at);
5300 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5301}
5302
5303void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5304 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005305 LOG_FUNC_SECTION {
5306 *Log << TU << ' ' << Range;
5307 }
5308
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005310 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 if (NumTokens)
5312 *NumTokens = 0;
5313
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005314 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005315 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005316 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005317 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005318
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005319 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 if (!CXXUnit || !Tokens || !NumTokens)
5321 return;
5322
5323 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5324
5325 SourceRange R = cxloc::translateCXSourceRange(Range);
5326 if (R.isInvalid())
5327 return;
5328
5329 SmallVector<CXToken, 32> CXTokens;
5330 getTokens(CXXUnit, R, CXTokens);
5331
5332 if (CXTokens.empty())
5333 return;
5334
5335 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5336 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5337 *NumTokens = CXTokens.size();
5338}
5339
5340void clang_disposeTokens(CXTranslationUnit TU,
5341 CXToken *Tokens, unsigned NumTokens) {
5342 free(Tokens);
5343}
5344
5345} // end: extern "C"
5346
5347//===----------------------------------------------------------------------===//
5348// Token annotation APIs.
5349//===----------------------------------------------------------------------===//
5350
Guy Benyei11169dd2012-12-18 14:30:41 +00005351static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5352 CXCursor parent,
5353 CXClientData client_data);
5354static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5355 CXClientData client_data);
5356
5357namespace {
5358class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 CXToken *Tokens;
5360 CXCursor *Cursors;
5361 unsigned NumTokens;
5362 unsigned TokIdx;
5363 unsigned PreprocessingTokIdx;
5364 CursorVisitor AnnotateVis;
5365 SourceManager &SrcMgr;
5366 bool HasContextSensitiveKeywords;
5367
5368 struct PostChildrenInfo {
5369 CXCursor Cursor;
5370 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005371 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 unsigned BeforeChildrenTokenIdx;
5373 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005374 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005375
5376 CXToken &getTok(unsigned Idx) {
5377 assert(Idx < NumTokens);
5378 return Tokens[Idx];
5379 }
5380 const CXToken &getTok(unsigned Idx) const {
5381 assert(Idx < NumTokens);
5382 return Tokens[Idx];
5383 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 bool MoreTokens() const { return TokIdx < NumTokens; }
5385 unsigned NextToken() const { return TokIdx; }
5386 void AdvanceToken() { ++TokIdx; }
5387 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005388 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 }
5390 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005391 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 }
5393 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005394 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 }
5396
5397 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005398 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 SourceRange);
5400
5401public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005402 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005403 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005404 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005406 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 AnnotateTokensVisitor, this,
5408 /*VisitPreprocessorLast=*/true,
5409 /*VisitIncludedEntities=*/false,
5410 RegionOfInterest,
5411 /*VisitDeclsOnly=*/false,
5412 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005413 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 HasContextSensitiveKeywords(false) { }
5415
5416 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5417 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5418 bool postVisitChildren(CXCursor cursor);
5419 void AnnotateTokens();
5420
5421 /// \brief Determine whether the annotator saw any cursors that have
5422 /// context-sensitive keywords.
5423 bool hasContextSensitiveKeywords() const {
5424 return HasContextSensitiveKeywords;
5425 }
5426
5427 ~AnnotateTokensWorker() {
5428 assert(PostChildrenInfos.empty());
5429 }
5430};
5431}
5432
5433void AnnotateTokensWorker::AnnotateTokens() {
5434 // Walk the AST within the region of interest, annotating tokens
5435 // along the way.
5436 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005437}
Guy Benyei11169dd2012-12-18 14:30:41 +00005438
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005439static inline void updateCursorAnnotation(CXCursor &Cursor,
5440 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005441 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005443 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005444}
5445
5446/// \brief It annotates and advances tokens with a cursor until the comparison
5447//// between the cursor location and the source range is the same as
5448/// \arg compResult.
5449///
5450/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5451/// Pass RangeOverlap to annotate tokens inside a range.
5452void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5453 RangeComparisonResult compResult,
5454 SourceRange range) {
5455 while (MoreTokens()) {
5456 const unsigned I = NextToken();
5457 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005458 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5459 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005460
5461 SourceLocation TokLoc = GetTokenLoc(I);
5462 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005463 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 AdvanceToken();
5465 continue;
5466 }
5467 break;
5468 }
5469}
5470
5471/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005472/// \returns true if it advanced beyond all macro tokens, false otherwise.
5473bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 CXCursor updateC,
5475 RangeComparisonResult compResult,
5476 SourceRange range) {
5477 assert(MoreTokens());
5478 assert(isFunctionMacroToken(NextToken()) &&
5479 "Should be called only for macro arg tokens");
5480
5481 // This works differently than annotateAndAdvanceTokens; because expanded
5482 // macro arguments can have arbitrary translation-unit source order, we do not
5483 // advance the token index one by one until a token fails the range test.
5484 // We only advance once past all of the macro arg tokens if all of them
5485 // pass the range test. If one of them fails we keep the token index pointing
5486 // at the start of the macro arg tokens so that the failing token will be
5487 // annotated by a subsequent annotation try.
5488
5489 bool atLeastOneCompFail = false;
5490
5491 unsigned I = NextToken();
5492 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5493 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5494 if (TokLoc.isFileID())
5495 continue; // not macro arg token, it's parens or comma.
5496 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5497 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5498 Cursors[I] = updateC;
5499 } else
5500 atLeastOneCompFail = true;
5501 }
5502
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005503 if (atLeastOneCompFail)
5504 return false;
5505
5506 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5507 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005508}
5509
5510enum CXChildVisitResult
5511AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 SourceRange cursorRange = getRawCursorExtent(cursor);
5513 if (cursorRange.isInvalid())
5514 return CXChildVisit_Recurse;
5515
5516 if (!HasContextSensitiveKeywords) {
5517 // Objective-C properties can have context-sensitive keywords.
5518 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005519 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5521 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5522 }
5523 // Objective-C methods can have context-sensitive keywords.
5524 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5525 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005526 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5528 if (Method->getObjCDeclQualifier())
5529 HasContextSensitiveKeywords = true;
5530 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005531 for (const auto *P : Method->params()) {
5532 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 HasContextSensitiveKeywords = true;
5534 break;
5535 }
5536 }
5537 }
5538 }
5539 }
5540 // C++ methods can have context-sensitive keywords.
5541 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005542 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5544 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5545 HasContextSensitiveKeywords = true;
5546 }
5547 }
5548 // C++ classes can have context-sensitive keywords.
5549 else if (cursor.kind == CXCursor_StructDecl ||
5550 cursor.kind == CXCursor_ClassDecl ||
5551 cursor.kind == CXCursor_ClassTemplate ||
5552 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005553 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 if (D->hasAttr<FinalAttr>())
5555 HasContextSensitiveKeywords = true;
5556 }
5557 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005558
5559 // Don't override a property annotation with its getter/setter method.
5560 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5561 parent.kind == CXCursor_ObjCPropertyDecl)
5562 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005563
5564 if (clang_isPreprocessing(cursor.kind)) {
5565 // Items in the preprocessing record are kept separate from items in
5566 // declarations, so we keep a separate token index.
5567 unsigned SavedTokIdx = TokIdx;
5568 TokIdx = PreprocessingTokIdx;
5569
5570 // Skip tokens up until we catch up to the beginning of the preprocessing
5571 // entry.
5572 while (MoreTokens()) {
5573 const unsigned I = NextToken();
5574 SourceLocation TokLoc = GetTokenLoc(I);
5575 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5576 case RangeBefore:
5577 AdvanceToken();
5578 continue;
5579 case RangeAfter:
5580 case RangeOverlap:
5581 break;
5582 }
5583 break;
5584 }
5585
5586 // Look at all of the tokens within this range.
5587 while (MoreTokens()) {
5588 const unsigned I = NextToken();
5589 SourceLocation TokLoc = GetTokenLoc(I);
5590 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5591 case RangeBefore:
5592 llvm_unreachable("Infeasible");
5593 case RangeAfter:
5594 break;
5595 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005596 // For macro expansions, just note where the beginning of the macro
5597 // expansion occurs.
5598 if (cursor.kind == CXCursor_MacroExpansion) {
5599 if (TokLoc == cursorRange.getBegin())
5600 Cursors[I] = cursor;
5601 AdvanceToken();
5602 break;
5603 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005604 // We may have already annotated macro names inside macro definitions.
5605 if (Cursors[I].kind != CXCursor_MacroExpansion)
5606 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 continue;
5609 }
5610 break;
5611 }
5612
5613 // Save the preprocessing token index; restore the non-preprocessing
5614 // token index.
5615 PreprocessingTokIdx = TokIdx;
5616 TokIdx = SavedTokIdx;
5617 return CXChildVisit_Recurse;
5618 }
5619
5620 if (cursorRange.isInvalid())
5621 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005622
5623 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 const enum CXCursorKind K = clang_getCursorKind(parent);
5626 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005627 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5628 // Attributes are annotated out-of-order, skip tokens until we reach it.
5629 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 ? clang_getNullCursor() : parent;
5631
5632 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5633
5634 // Avoid having the cursor of an expression "overwrite" the annotation of the
5635 // variable declaration that it belongs to.
5636 // This can happen for C++ constructor expressions whose range generally
5637 // include the variable declaration, e.g.:
5638 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005639 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005640 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005641 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 const unsigned I = NextToken();
5643 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5644 E->getLocStart() == D->getLocation() &&
5645 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005646 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 AdvanceToken();
5648 }
5649 }
5650 }
5651
5652 // Before recursing into the children keep some state that we are going
5653 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5654 // extra work after the child nodes are visited.
5655 // Note that we don't call VisitChildren here to avoid traversing statements
5656 // code-recursively which can blow the stack.
5657
5658 PostChildrenInfo Info;
5659 Info.Cursor = cursor;
5660 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005661 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 Info.BeforeChildrenTokenIdx = NextToken();
5663 PostChildrenInfos.push_back(Info);
5664
5665 return CXChildVisit_Recurse;
5666}
5667
5668bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5669 if (PostChildrenInfos.empty())
5670 return false;
5671 const PostChildrenInfo &Info = PostChildrenInfos.back();
5672 if (!clang_equalCursors(Info.Cursor, cursor))
5673 return false;
5674
5675 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5676 const unsigned AfterChildren = NextToken();
5677 SourceRange cursorRange = Info.CursorRange;
5678
5679 // Scan the tokens that are at the end of the cursor, but are not captured
5680 // but the child cursors.
5681 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5682
5683 // Scan the tokens that are at the beginning of the cursor, but are not
5684 // capture by the child cursors.
5685 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5686 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5687 break;
5688
5689 Cursors[I] = cursor;
5690 }
5691
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005692 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5693 // encountered the attribute cursor.
5694 if (clang_isAttribute(cursor.kind))
5695 TokIdx = Info.BeforeReachingCursorIdx;
5696
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 PostChildrenInfos.pop_back();
5698 return false;
5699}
5700
5701static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5702 CXCursor parent,
5703 CXClientData client_data) {
5704 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5705}
5706
5707static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5708 CXClientData client_data) {
5709 return static_cast<AnnotateTokensWorker*>(client_data)->
5710 postVisitChildren(cursor);
5711}
5712
5713namespace {
5714
5715/// \brief Uses the macro expansions in the preprocessing record to find
5716/// and mark tokens that are macro arguments. This info is used by the
5717/// AnnotateTokensWorker.
5718class MarkMacroArgTokensVisitor {
5719 SourceManager &SM;
5720 CXToken *Tokens;
5721 unsigned NumTokens;
5722 unsigned CurIdx;
5723
5724public:
5725 MarkMacroArgTokensVisitor(SourceManager &SM,
5726 CXToken *tokens, unsigned numTokens)
5727 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5728
5729 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5730 if (cursor.kind != CXCursor_MacroExpansion)
5731 return CXChildVisit_Continue;
5732
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005733 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 if (macroRange.getBegin() == macroRange.getEnd())
5735 return CXChildVisit_Continue; // it's not a function macro.
5736
5737 for (; CurIdx < NumTokens; ++CurIdx) {
5738 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5739 macroRange.getBegin()))
5740 break;
5741 }
5742
5743 if (CurIdx == NumTokens)
5744 return CXChildVisit_Break;
5745
5746 for (; CurIdx < NumTokens; ++CurIdx) {
5747 SourceLocation tokLoc = getTokenLoc(CurIdx);
5748 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5749 break;
5750
5751 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5752 }
5753
5754 if (CurIdx == NumTokens)
5755 return CXChildVisit_Break;
5756
5757 return CXChildVisit_Continue;
5758 }
5759
5760private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005761 CXToken &getTok(unsigned Idx) {
5762 assert(Idx < NumTokens);
5763 return Tokens[Idx];
5764 }
5765 const CXToken &getTok(unsigned Idx) const {
5766 assert(Idx < NumTokens);
5767 return Tokens[Idx];
5768 }
5769
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005771 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 }
5773
5774 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5775 // The third field is reserved and currently not used. Use it here
5776 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005777 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 }
5779};
5780
5781} // end anonymous namespace
5782
5783static CXChildVisitResult
5784MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5785 CXClientData client_data) {
5786 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5787 parent);
5788}
5789
5790namespace {
5791 struct clang_annotateTokens_Data {
5792 CXTranslationUnit TU;
5793 ASTUnit *CXXUnit;
5794 CXToken *Tokens;
5795 unsigned NumTokens;
5796 CXCursor *Cursors;
5797 };
5798}
5799
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800/// \brief Used by \c annotatePreprocessorTokens.
5801/// \returns true if lexing was finished, false otherwise.
5802static bool lexNext(Lexer &Lex, Token &Tok,
5803 unsigned &NextIdx, unsigned NumTokens) {
5804 if (NextIdx >= NumTokens)
5805 return true;
5806
5807 ++NextIdx;
5808 Lex.LexFromRawLexer(Tok);
5809 if (Tok.is(tok::eof))
5810 return true;
5811
5812 return false;
5813}
5814
Guy Benyei11169dd2012-12-18 14:30:41 +00005815static void annotatePreprocessorTokens(CXTranslationUnit TU,
5816 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005817 CXCursor *Cursors,
5818 CXToken *Tokens,
5819 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005820 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005821
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005822 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5824 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005825 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005827 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005828
5829 if (BeginLocInfo.first != EndLocInfo.first)
5830 return;
5831
5832 StringRef Buffer;
5833 bool Invalid = false;
5834 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5835 if (Buffer.empty() || Invalid)
5836 return;
5837
5838 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5839 CXXUnit->getASTContext().getLangOpts(),
5840 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5841 Buffer.end());
5842 Lex.SetCommentRetentionState(true);
5843
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005844 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 // Lex tokens in raw mode until we hit the end of the range, to avoid
5846 // entering #includes or expanding macros.
5847 while (true) {
5848 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5850 break;
5851 unsigned TokIdx = NextIdx-1;
5852 assert(Tok.getLocation() ==
5853 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005854
5855 reprocess:
5856 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005857 // We have found a preprocessing directive. Annotate the tokens
5858 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 //
5860 // FIXME: Some simple tests here could identify macro definitions and
5861 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005862
5863 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005864 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5865 break;
5866
Craig Topper69186e72014-06-08 08:38:04 +00005867 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005868 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005869 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5870 break;
5871
5872 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005873 IdentifierInfo &II =
5874 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005875 SourceLocation MappedTokLoc =
5876 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5877 MI = getMacroInfo(II, MappedTokLoc, TU);
5878 }
5879 }
5880
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005881 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005883 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5884 finished = true;
5885 break;
5886 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005887 // If we are in a macro definition, check if the token was ever a
5888 // macro name and annotate it if that's the case.
5889 if (MI) {
5890 SourceLocation SaveLoc = Tok.getLocation();
5891 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5892 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5893 Tok.setLocation(SaveLoc);
5894 if (MacroDef)
5895 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5896 Tok.getLocation(), TU);
5897 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005898 } while (!Tok.isAtStartOfLine());
5899
5900 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5901 assert(TokIdx <= LastIdx);
5902 SourceLocation EndLoc =
5903 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5904 CXCursor Cursor =
5905 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5906
5907 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005908 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005909
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005910 if (finished)
5911 break;
5912 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 }
5915}
5916
5917// This gets run a separate thread to avoid stack blowout.
5918static void clang_annotateTokensImpl(void *UserData) {
5919 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5920 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5921 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5922 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5923 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5924
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005925 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5927 setThreadBackgroundPriority();
5928
5929 // Determine the region of interest, which contains all of the tokens.
5930 SourceRange RegionOfInterest;
5931 RegionOfInterest.setBegin(
5932 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5933 RegionOfInterest.setEnd(
5934 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5935 Tokens[NumTokens-1])));
5936
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 // Relex the tokens within the source range to look for preprocessing
5938 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005939 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005940
5941 // If begin location points inside a macro argument, set it to the expansion
5942 // location so we can have the full context when annotating semantically.
5943 {
5944 SourceManager &SM = CXXUnit->getSourceManager();
5945 SourceLocation Loc =
5946 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5947 if (Loc.isMacroID())
5948 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5949 }
5950
Guy Benyei11169dd2012-12-18 14:30:41 +00005951 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5952 // Search and mark tokens that are macro argument expansions.
5953 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5954 Tokens, NumTokens);
5955 CursorVisitor MacroArgMarker(TU,
5956 MarkMacroArgTokensVisitorDelegate, &Visitor,
5957 /*VisitPreprocessorLast=*/true,
5958 /*VisitIncludedEntities=*/false,
5959 RegionOfInterest);
5960 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5961 }
5962
5963 // Annotate all of the source locations in the region of interest that map to
5964 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005965 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005966
5967 // FIXME: We use a ridiculous stack size here because the data-recursion
5968 // algorithm uses a large stack frame than the non-data recursive version,
5969 // and AnnotationTokensWorker currently transforms the data-recursion
5970 // algorithm back into a traditional recursion by explicitly calling
5971 // VisitChildren(). We will need to remove this explicit recursive call.
5972 W.AnnotateTokens();
5973
5974 // If we ran into any entities that involve context-sensitive keywords,
5975 // take another pass through the tokens to mark them as such.
5976 if (W.hasContextSensitiveKeywords()) {
5977 for (unsigned I = 0; I != NumTokens; ++I) {
5978 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5979 continue;
5980
5981 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5982 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005983 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005984 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5985 if (Property->getPropertyAttributesAsWritten() != 0 &&
5986 llvm::StringSwitch<bool>(II->getName())
5987 .Case("readonly", true)
5988 .Case("assign", true)
5989 .Case("unsafe_unretained", true)
5990 .Case("readwrite", true)
5991 .Case("retain", true)
5992 .Case("copy", true)
5993 .Case("nonatomic", true)
5994 .Case("atomic", true)
5995 .Case("getter", true)
5996 .Case("setter", true)
5997 .Case("strong", true)
5998 .Case("weak", true)
5999 .Default(false))
6000 Tokens[I].int_data[0] = CXToken_Keyword;
6001 }
6002 continue;
6003 }
6004
6005 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6006 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6007 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6008 if (llvm::StringSwitch<bool>(II->getName())
6009 .Case("in", true)
6010 .Case("out", true)
6011 .Case("inout", true)
6012 .Case("oneway", true)
6013 .Case("bycopy", true)
6014 .Case("byref", true)
6015 .Default(false))
6016 Tokens[I].int_data[0] = CXToken_Keyword;
6017 continue;
6018 }
6019
6020 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6021 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6022 Tokens[I].int_data[0] = CXToken_Keyword;
6023 continue;
6024 }
6025 }
6026 }
6027}
6028
6029extern "C" {
6030
6031void clang_annotateTokens(CXTranslationUnit TU,
6032 CXToken *Tokens, unsigned NumTokens,
6033 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006034 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006035 LOG_BAD_TU(TU);
6036 return;
6037 }
6038 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006039 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006041 }
6042
6043 LOG_FUNC_SECTION {
6044 *Log << TU << ' ';
6045 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6046 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6047 *Log << clang_getRange(bloc, eloc);
6048 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006049
6050 // Any token we don't specifically annotate will have a NULL cursor.
6051 CXCursor C = clang_getNullCursor();
6052 for (unsigned I = 0; I != NumTokens; ++I)
6053 Cursors[I] = C;
6054
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006056 if (!CXXUnit)
6057 return;
6058
6059 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6060
6061 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6062 llvm::CrashRecoveryContext CRC;
6063 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6064 GetSafetyThreadStackSize() * 2)) {
6065 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6066 }
6067}
6068
6069} // end: extern "C"
6070
6071//===----------------------------------------------------------------------===//
6072// Operations for querying linkage of a cursor.
6073//===----------------------------------------------------------------------===//
6074
6075extern "C" {
6076CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6077 if (!clang_isDeclaration(cursor.kind))
6078 return CXLinkage_Invalid;
6079
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006080 const Decl *D = cxcursor::getCursorDecl(cursor);
6081 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006082 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006083 case NoLinkage:
6084 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 case InternalLinkage: return CXLinkage_Internal;
6086 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6087 case ExternalLinkage: return CXLinkage_External;
6088 };
6089
6090 return CXLinkage_Invalid;
6091}
6092} // end: extern "C"
6093
6094//===----------------------------------------------------------------------===//
6095// Operations for querying language of a cursor.
6096//===----------------------------------------------------------------------===//
6097
6098static CXLanguageKind getDeclLanguage(const Decl *D) {
6099 if (!D)
6100 return CXLanguage_C;
6101
6102 switch (D->getKind()) {
6103 default:
6104 break;
6105 case Decl::ImplicitParam:
6106 case Decl::ObjCAtDefsField:
6107 case Decl::ObjCCategory:
6108 case Decl::ObjCCategoryImpl:
6109 case Decl::ObjCCompatibleAlias:
6110 case Decl::ObjCImplementation:
6111 case Decl::ObjCInterface:
6112 case Decl::ObjCIvar:
6113 case Decl::ObjCMethod:
6114 case Decl::ObjCProperty:
6115 case Decl::ObjCPropertyImpl:
6116 case Decl::ObjCProtocol:
6117 return CXLanguage_ObjC;
6118 case Decl::CXXConstructor:
6119 case Decl::CXXConversion:
6120 case Decl::CXXDestructor:
6121 case Decl::CXXMethod:
6122 case Decl::CXXRecord:
6123 case Decl::ClassTemplate:
6124 case Decl::ClassTemplatePartialSpecialization:
6125 case Decl::ClassTemplateSpecialization:
6126 case Decl::Friend:
6127 case Decl::FriendTemplate:
6128 case Decl::FunctionTemplate:
6129 case Decl::LinkageSpec:
6130 case Decl::Namespace:
6131 case Decl::NamespaceAlias:
6132 case Decl::NonTypeTemplateParm:
6133 case Decl::StaticAssert:
6134 case Decl::TemplateTemplateParm:
6135 case Decl::TemplateTypeParm:
6136 case Decl::UnresolvedUsingTypename:
6137 case Decl::UnresolvedUsingValue:
6138 case Decl::Using:
6139 case Decl::UsingDirective:
6140 case Decl::UsingShadow:
6141 return CXLanguage_CPlusPlus;
6142 }
6143
6144 return CXLanguage_C;
6145}
6146
6147extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006148
6149static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6150 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6151 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006152
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006153 switch (D->getAvailability()) {
6154 case AR_Available:
6155 case AR_NotYetIntroduced:
6156 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006157 return getCursorAvailabilityForDecl(
6158 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006159 return CXAvailability_Available;
6160
6161 case AR_Deprecated:
6162 return CXAvailability_Deprecated;
6163
6164 case AR_Unavailable:
6165 return CXAvailability_NotAvailable;
6166 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006167
6168 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006169}
6170
Guy Benyei11169dd2012-12-18 14:30:41 +00006171enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6172 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006173 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6174 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006175
6176 return CXAvailability_Available;
6177}
6178
6179static CXVersion convertVersion(VersionTuple In) {
6180 CXVersion Out = { -1, -1, -1 };
6181 if (In.empty())
6182 return Out;
6183
6184 Out.Major = In.getMajor();
6185
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006186 Optional<unsigned> Minor = In.getMinor();
6187 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 Out.Minor = *Minor;
6189 else
6190 return Out;
6191
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006192 Optional<unsigned> Subminor = In.getSubminor();
6193 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 Out.Subminor = *Subminor;
6195
6196 return Out;
6197}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006198
6199static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6200 int *always_deprecated,
6201 CXString *deprecated_message,
6202 int *always_unavailable,
6203 CXString *unavailable_message,
6204 CXPlatformAvailability *availability,
6205 int availability_size) {
6206 bool HadAvailAttr = false;
6207 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006208 for (auto A : D->attrs()) {
6209 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006210 HadAvailAttr = true;
6211 if (always_deprecated)
6212 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006213 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006214 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006215 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006216 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006217 continue;
6218 }
6219
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006220 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006221 HadAvailAttr = true;
6222 if (always_unavailable)
6223 *always_unavailable = 1;
6224 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006225 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006226 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6227 }
6228 continue;
6229 }
6230
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006231 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006232 HadAvailAttr = true;
6233 if (N < availability_size) {
6234 availability[N].Platform
6235 = cxstring::createDup(Avail->getPlatform()->getName());
6236 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6237 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6238 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6239 availability[N].Unavailable = Avail->getUnavailable();
6240 availability[N].Message = cxstring::createDup(Avail->getMessage());
6241 }
6242 ++N;
6243 }
6244 }
6245
6246 if (!HadAvailAttr)
6247 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6248 return getCursorPlatformAvailabilityForDecl(
6249 cast<Decl>(EnumConst->getDeclContext()),
6250 always_deprecated,
6251 deprecated_message,
6252 always_unavailable,
6253 unavailable_message,
6254 availability,
6255 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006256
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006257 return N;
6258}
6259
Guy Benyei11169dd2012-12-18 14:30:41 +00006260int clang_getCursorPlatformAvailability(CXCursor cursor,
6261 int *always_deprecated,
6262 CXString *deprecated_message,
6263 int *always_unavailable,
6264 CXString *unavailable_message,
6265 CXPlatformAvailability *availability,
6266 int availability_size) {
6267 if (always_deprecated)
6268 *always_deprecated = 0;
6269 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006270 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006271 if (always_unavailable)
6272 *always_unavailable = 0;
6273 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006274 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006275
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 if (!clang_isDeclaration(cursor.kind))
6277 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006279 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 if (!D)
6281 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006282
6283 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6284 deprecated_message,
6285 always_unavailable,
6286 unavailable_message,
6287 availability,
6288 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006289}
6290
6291void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6292 clang_disposeString(availability->Platform);
6293 clang_disposeString(availability->Message);
6294}
6295
6296CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6297 if (clang_isDeclaration(cursor.kind))
6298 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6299
6300 return CXLanguage_Invalid;
6301}
6302
6303 /// \brief If the given cursor is the "templated" declaration
6304 /// descibing a class or function template, return the class or
6305 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006306static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006308 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006309
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006310 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6312 return FunTmpl;
6313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006314 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6316 return ClassTmpl;
6317
6318 return D;
6319}
6320
6321CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6322 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006323 if (const Decl *D = getCursorDecl(cursor)) {
6324 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006325 if (!DC)
6326 return clang_getNullCursor();
6327
6328 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6329 getCursorTU(cursor));
6330 }
6331 }
6332
6333 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006334 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 return MakeCXCursor(D, getCursorTU(cursor));
6336 }
6337
6338 return clang_getNullCursor();
6339}
6340
6341CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6342 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006343 if (const Decl *D = getCursorDecl(cursor)) {
6344 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006345 if (!DC)
6346 return clang_getNullCursor();
6347
6348 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6349 getCursorTU(cursor));
6350 }
6351 }
6352
6353 // FIXME: Note that we can't easily compute the lexical context of a
6354 // statement or expression, so we return nothing.
6355 return clang_getNullCursor();
6356}
6357
6358CXFile clang_getIncludedFile(CXCursor cursor) {
6359 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006360 return nullptr;
6361
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006362 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006363 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006366unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6367 if (C.kind != CXCursor_ObjCPropertyDecl)
6368 return CXObjCPropertyAttr_noattr;
6369
6370 unsigned Result = CXObjCPropertyAttr_noattr;
6371 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6372 ObjCPropertyDecl::PropertyAttributeKind Attr =
6373 PD->getPropertyAttributesAsWritten();
6374
6375#define SET_CXOBJCPROP_ATTR(A) \
6376 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6377 Result |= CXObjCPropertyAttr_##A
6378 SET_CXOBJCPROP_ATTR(readonly);
6379 SET_CXOBJCPROP_ATTR(getter);
6380 SET_CXOBJCPROP_ATTR(assign);
6381 SET_CXOBJCPROP_ATTR(readwrite);
6382 SET_CXOBJCPROP_ATTR(retain);
6383 SET_CXOBJCPROP_ATTR(copy);
6384 SET_CXOBJCPROP_ATTR(nonatomic);
6385 SET_CXOBJCPROP_ATTR(setter);
6386 SET_CXOBJCPROP_ATTR(atomic);
6387 SET_CXOBJCPROP_ATTR(weak);
6388 SET_CXOBJCPROP_ATTR(strong);
6389 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6390#undef SET_CXOBJCPROP_ATTR
6391
6392 return Result;
6393}
6394
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006395unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6396 if (!clang_isDeclaration(C.kind))
6397 return CXObjCDeclQualifier_None;
6398
6399 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6400 const Decl *D = getCursorDecl(C);
6401 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6402 QT = MD->getObjCDeclQualifier();
6403 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6404 QT = PD->getObjCDeclQualifier();
6405 if (QT == Decl::OBJC_TQ_None)
6406 return CXObjCDeclQualifier_None;
6407
6408 unsigned Result = CXObjCDeclQualifier_None;
6409 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6410 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6411 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6412 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6413 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6414 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6415
6416 return Result;
6417}
6418
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006419unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6420 if (!clang_isDeclaration(C.kind))
6421 return 0;
6422
6423 const Decl *D = getCursorDecl(C);
6424 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6425 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6426 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6427 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6428
6429 return 0;
6430}
6431
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006432unsigned clang_Cursor_isVariadic(CXCursor C) {
6433 if (!clang_isDeclaration(C.kind))
6434 return 0;
6435
6436 const Decl *D = getCursorDecl(C);
6437 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6438 return FD->isVariadic();
6439 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6440 return MD->isVariadic();
6441
6442 return 0;
6443}
6444
Guy Benyei11169dd2012-12-18 14:30:41 +00006445CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6446 if (!clang_isDeclaration(C.kind))
6447 return clang_getNullRange();
6448
6449 const Decl *D = getCursorDecl(C);
6450 ASTContext &Context = getCursorContext(C);
6451 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6452 if (!RC)
6453 return clang_getNullRange();
6454
6455 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6456}
6457
6458CXString clang_Cursor_getRawCommentText(CXCursor C) {
6459 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006460 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006461
6462 const Decl *D = getCursorDecl(C);
6463 ASTContext &Context = getCursorContext(C);
6464 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6465 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6466 StringRef();
6467
6468 // Don't duplicate the string because RawText points directly into source
6469 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006470 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006471}
6472
6473CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6474 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006475 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006476
6477 const Decl *D = getCursorDecl(C);
6478 const ASTContext &Context = getCursorContext(C);
6479 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6480
6481 if (RC) {
6482 StringRef BriefText = RC->getBriefText(Context);
6483
6484 // Don't duplicate the string because RawComment ensures that this memory
6485 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006486 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006487 }
6488
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006489 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006490}
6491
Guy Benyei11169dd2012-12-18 14:30:41 +00006492CXModule clang_Cursor_getModule(CXCursor C) {
6493 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006494 if (const ImportDecl *ImportD =
6495 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 return ImportD->getImportedModule();
6497 }
6498
Craig Topper69186e72014-06-08 08:38:04 +00006499 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006500}
6501
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006502CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6503 if (isNotUsableTU(TU)) {
6504 LOG_BAD_TU(TU);
6505 return nullptr;
6506 }
6507 if (!File)
6508 return nullptr;
6509 FileEntry *FE = static_cast<FileEntry *>(File);
6510
6511 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6512 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6513 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6514
6515 if (Module *Mod = Header.getModule()) {
6516 if (Header.getRole() != ModuleMap::ExcludedHeader)
6517 return Mod;
6518 }
6519 return nullptr;
6520}
6521
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006522CXFile clang_Module_getASTFile(CXModule CXMod) {
6523 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006524 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006525 Module *Mod = static_cast<Module*>(CXMod);
6526 return const_cast<FileEntry *>(Mod->getASTFile());
6527}
6528
Guy Benyei11169dd2012-12-18 14:30:41 +00006529CXModule clang_Module_getParent(CXModule CXMod) {
6530 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006531 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 Module *Mod = static_cast<Module*>(CXMod);
6533 return Mod->Parent;
6534}
6535
6536CXString clang_Module_getName(CXModule CXMod) {
6537 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006538 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006539 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006540 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006541}
6542
6543CXString clang_Module_getFullName(CXModule CXMod) {
6544 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006545 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006547 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006548}
6549
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006550int clang_Module_isSystem(CXModule CXMod) {
6551 if (!CXMod)
6552 return 0;
6553 Module *Mod = static_cast<Module*>(CXMod);
6554 return Mod->IsSystem;
6555}
6556
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006557unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6558 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006559 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006560 LOG_BAD_TU(TU);
6561 return 0;
6562 }
6563 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006564 return 0;
6565 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006566 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6567 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6568 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006569}
6570
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006571CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6572 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006573 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006574 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006575 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006576 }
6577 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006578 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006580 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006581
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006582 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6583 if (Index < TopHeaders.size())
6584 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006585
Craig Topper69186e72014-06-08 08:38:04 +00006586 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006587}
6588
6589} // end: extern "C"
6590
6591//===----------------------------------------------------------------------===//
6592// C++ AST instrospection.
6593//===----------------------------------------------------------------------===//
6594
6595extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006596unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6597 if (!clang_isDeclaration(C.kind))
6598 return 0;
6599
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006600 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006601 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006602 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006603 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6604}
6605
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006606unsigned clang_CXXMethod_isConst(CXCursor C) {
6607 if (!clang_isDeclaration(C.kind))
6608 return 0;
6609
6610 const Decl *D = cxcursor::getCursorDecl(C);
6611 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006612 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006613 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6614}
6615
Guy Benyei11169dd2012-12-18 14:30:41 +00006616unsigned clang_CXXMethod_isStatic(CXCursor C) {
6617 if (!clang_isDeclaration(C.kind))
6618 return 0;
6619
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006620 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006621 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006622 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 return (Method && Method->isStatic()) ? 1 : 0;
6624}
6625
6626unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6627 if (!clang_isDeclaration(C.kind))
6628 return 0;
6629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006630 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006631 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006632 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 return (Method && Method->isVirtual()) ? 1 : 0;
6634}
6635} // end: extern "C"
6636
6637//===----------------------------------------------------------------------===//
6638// Attribute introspection.
6639//===----------------------------------------------------------------------===//
6640
6641extern "C" {
6642CXType clang_getIBOutletCollectionType(CXCursor C) {
6643 if (C.kind != CXCursor_IBOutletCollectionAttr)
6644 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6645
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006646 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6648
6649 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6650}
6651} // end: extern "C"
6652
6653//===----------------------------------------------------------------------===//
6654// Inspecting memory usage.
6655//===----------------------------------------------------------------------===//
6656
6657typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6658
6659static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6660 enum CXTUResourceUsageKind k,
6661 unsigned long amount) {
6662 CXTUResourceUsageEntry entry = { k, amount };
6663 entries.push_back(entry);
6664}
6665
6666extern "C" {
6667
6668const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6669 const char *str = "";
6670 switch (kind) {
6671 case CXTUResourceUsage_AST:
6672 str = "ASTContext: expressions, declarations, and types";
6673 break;
6674 case CXTUResourceUsage_Identifiers:
6675 str = "ASTContext: identifiers";
6676 break;
6677 case CXTUResourceUsage_Selectors:
6678 str = "ASTContext: selectors";
6679 break;
6680 case CXTUResourceUsage_GlobalCompletionResults:
6681 str = "Code completion: cached global results";
6682 break;
6683 case CXTUResourceUsage_SourceManagerContentCache:
6684 str = "SourceManager: content cache allocator";
6685 break;
6686 case CXTUResourceUsage_AST_SideTables:
6687 str = "ASTContext: side tables";
6688 break;
6689 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6690 str = "SourceManager: malloc'ed memory buffers";
6691 break;
6692 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6693 str = "SourceManager: mmap'ed memory buffers";
6694 break;
6695 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6696 str = "ExternalASTSource: malloc'ed memory buffers";
6697 break;
6698 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6699 str = "ExternalASTSource: mmap'ed memory buffers";
6700 break;
6701 case CXTUResourceUsage_Preprocessor:
6702 str = "Preprocessor: malloc'ed memory";
6703 break;
6704 case CXTUResourceUsage_PreprocessingRecord:
6705 str = "Preprocessor: PreprocessingRecord";
6706 break;
6707 case CXTUResourceUsage_SourceManager_DataStructures:
6708 str = "SourceManager: data structures and tables";
6709 break;
6710 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6711 str = "Preprocessor: header search tables";
6712 break;
6713 }
6714 return str;
6715}
6716
6717CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006718 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006719 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006720 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 return usage;
6722 }
6723
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006724 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006725 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006726 ASTContext &astContext = astUnit->getASTContext();
6727
6728 // How much memory is used by AST nodes and types?
6729 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6730 (unsigned long) astContext.getASTAllocatedMemory());
6731
6732 // How much memory is used by identifiers?
6733 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6734 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6735
6736 // How much memory is used for selectors?
6737 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6738 (unsigned long) astContext.Selectors.getTotalMemory());
6739
6740 // How much memory is used by ASTContext's side tables?
6741 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6742 (unsigned long) astContext.getSideTableAllocatedMemory());
6743
6744 // How much memory is used for caching global code completion results?
6745 unsigned long completionBytes = 0;
6746 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006747 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 completionBytes = completionAllocator->getTotalMemory();
6749 }
6750 createCXTUResourceUsageEntry(*entries,
6751 CXTUResourceUsage_GlobalCompletionResults,
6752 completionBytes);
6753
6754 // How much memory is being used by SourceManager's content cache?
6755 createCXTUResourceUsageEntry(*entries,
6756 CXTUResourceUsage_SourceManagerContentCache,
6757 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6758
6759 // How much memory is being used by the MemoryBuffer's in SourceManager?
6760 const SourceManager::MemoryBufferSizes &srcBufs =
6761 astUnit->getSourceManager().getMemoryBufferSizes();
6762
6763 createCXTUResourceUsageEntry(*entries,
6764 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6765 (unsigned long) srcBufs.malloc_bytes);
6766 createCXTUResourceUsageEntry(*entries,
6767 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6768 (unsigned long) srcBufs.mmap_bytes);
6769 createCXTUResourceUsageEntry(*entries,
6770 CXTUResourceUsage_SourceManager_DataStructures,
6771 (unsigned long) astContext.getSourceManager()
6772 .getDataStructureSizes());
6773
6774 // How much memory is being used by the ExternalASTSource?
6775 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6776 const ExternalASTSource::MemoryBufferSizes &sizes =
6777 esrc->getMemoryBufferSizes();
6778
6779 createCXTUResourceUsageEntry(*entries,
6780 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6781 (unsigned long) sizes.malloc_bytes);
6782 createCXTUResourceUsageEntry(*entries,
6783 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6784 (unsigned long) sizes.mmap_bytes);
6785 }
6786
6787 // How much memory is being used by the Preprocessor?
6788 Preprocessor &pp = astUnit->getPreprocessor();
6789 createCXTUResourceUsageEntry(*entries,
6790 CXTUResourceUsage_Preprocessor,
6791 pp.getTotalMemory());
6792
6793 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6794 createCXTUResourceUsageEntry(*entries,
6795 CXTUResourceUsage_PreprocessingRecord,
6796 pRec->getTotalMemory());
6797 }
6798
6799 createCXTUResourceUsageEntry(*entries,
6800 CXTUResourceUsage_Preprocessor_HeaderSearch,
6801 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006802
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 CXTUResourceUsage usage = { (void*) entries.get(),
6804 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006805 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006806 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006807 return usage;
6808}
6809
6810void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6811 if (usage.data)
6812 delete (MemUsageEntries*) usage.data;
6813}
6814
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006815CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6816 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006817 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006818 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006819
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006820 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006821 LOG_BAD_TU(TU);
6822 return skipped;
6823 }
6824
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006825 if (!file)
6826 return skipped;
6827
6828 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6829 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6830 if (!ppRec)
6831 return skipped;
6832
6833 ASTContext &Ctx = astUnit->getASTContext();
6834 SourceManager &sm = Ctx.getSourceManager();
6835 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6836 FileID wantedFileID = sm.translateFile(fileEntry);
6837
6838 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6839 std::vector<SourceRange> wantedRanges;
6840 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6841 i != ei; ++i) {
6842 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6843 wantedRanges.push_back(*i);
6844 }
6845
6846 skipped->count = wantedRanges.size();
6847 skipped->ranges = new CXSourceRange[skipped->count];
6848 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6849 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6850
6851 return skipped;
6852}
6853
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006854void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6855 if (ranges) {
6856 delete[] ranges->ranges;
6857 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006858 }
6859}
6860
Guy Benyei11169dd2012-12-18 14:30:41 +00006861} // end extern "C"
6862
6863void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6864 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6865 for (unsigned I = 0; I != Usage.numEntries; ++I)
6866 fprintf(stderr, " %s: %lu\n",
6867 clang_getTUResourceUsageName(Usage.entries[I].kind),
6868 Usage.entries[I].amount);
6869
6870 clang_disposeCXTUResourceUsage(Usage);
6871}
6872
6873//===----------------------------------------------------------------------===//
6874// Misc. utility functions.
6875//===----------------------------------------------------------------------===//
6876
6877/// Default to using an 8 MB stack size on "safety" threads.
6878static unsigned SafetyStackThreadSize = 8 << 20;
6879
6880namespace clang {
6881
6882bool RunSafely(llvm::CrashRecoveryContext &CRC,
6883 void (*Fn)(void*), void *UserData,
6884 unsigned Size) {
6885 if (!Size)
6886 Size = GetSafetyThreadStackSize();
6887 if (Size)
6888 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6889 return CRC.RunSafely(Fn, UserData);
6890}
6891
6892unsigned GetSafetyThreadStackSize() {
6893 return SafetyStackThreadSize;
6894}
6895
6896void SetSafetyThreadStackSize(unsigned Value) {
6897 SafetyStackThreadSize = Value;
6898}
6899
6900}
6901
6902void clang::setThreadBackgroundPriority() {
6903 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6904 return;
6905
Alp Toker1a86ad22014-07-06 06:24:00 +00006906#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006907 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6908#endif
6909}
6910
6911void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6912 if (!Unit)
6913 return;
6914
6915 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6916 DEnd = Unit->stored_diag_end();
6917 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006918 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006919 CXString Msg = clang_formatDiagnostic(&Diag,
6920 clang_defaultDiagnosticDisplayOptions());
6921 fprintf(stderr, "%s\n", clang_getCString(Msg));
6922 clang_disposeString(Msg);
6923 }
6924#ifdef LLVM_ON_WIN32
6925 // On Windows, force a flush, since there may be multiple copies of
6926 // stderr and stdout in the file system, all with different buffers
6927 // but writing to the same device.
6928 fflush(stderr);
6929#endif
6930}
6931
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006932MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6933 SourceLocation MacroDefLoc,
6934 CXTranslationUnit TU){
6935 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006936 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006937 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006938 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006939
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006940 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006941 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006942 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006943 if (MD) {
6944 for (MacroDirective::DefInfo
6945 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6946 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6947 return Def.getMacroInfo();
6948 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006949 }
6950
Craig Topper69186e72014-06-08 08:38:04 +00006951 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006952}
6953
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006954const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6955 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006956 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006957 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006958 const IdentifierInfo *II = MacroDef->getName();
6959 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006960 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006961
6962 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6963}
6964
6965MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6966 const Token &Tok,
6967 CXTranslationUnit TU) {
6968 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006969 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006970 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006971 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006972
6973 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006974 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006975 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6976 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006977 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006978
6979 // Check that the token is inside the definition and not its argument list.
6980 SourceManager &SM = Unit->getSourceManager();
6981 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006982 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006983 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006984 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006985
6986 Preprocessor &PP = Unit->getPreprocessor();
6987 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6988 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006989 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006990
Alp Toker2d57cea2014-05-17 04:53:25 +00006991 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006992 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006993 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006994
6995 // Check that the identifier is not one of the macro arguments.
6996 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006997 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006998
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006999 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7000 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007001 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007002
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007003 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007004}
7005
7006MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7007 SourceLocation Loc,
7008 CXTranslationUnit TU) {
7009 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007010 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007011
7012 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007013 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007014 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007015 Preprocessor &PP = Unit->getPreprocessor();
7016 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007017 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007018 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7019 Token Tok;
7020 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007021 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007022
7023 return checkForMacroInMacroDefinition(MI, Tok, TU);
7024}
7025
Guy Benyei11169dd2012-12-18 14:30:41 +00007026extern "C" {
7027
7028CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007029 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007030}
7031
7032} // end: extern "C"
7033
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007034Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7035 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007036 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007037 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007038 if (Unit->isMainFileAST())
7039 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007040 return *this;
7041 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007042 } else {
7043 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007044 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007045 return *this;
7046}
7047
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007048Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7049 *this << FE->getName();
7050 return *this;
7051}
7052
7053Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7054 CXString cursorName = clang_getCursorDisplayName(cursor);
7055 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7056 clang_disposeString(cursorName);
7057 return *this;
7058}
7059
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007060Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7061 CXFile File;
7062 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007063 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007064 CXString FileName = clang_getFileName(File);
7065 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7066 clang_disposeString(FileName);
7067 return *this;
7068}
7069
7070Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7071 CXSourceLocation BLoc = clang_getRangeStart(range);
7072 CXSourceLocation ELoc = clang_getRangeEnd(range);
7073
7074 CXFile BFile;
7075 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007076 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007077
7078 CXFile EFile;
7079 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007080 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007081
7082 CXString BFileName = clang_getFileName(BFile);
7083 if (BFile == EFile) {
7084 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7085 BLine, BColumn, ELine, EColumn);
7086 } else {
7087 CXString EFileName = clang_getFileName(EFile);
7088 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7089 BLine, BColumn)
7090 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7091 ELine, EColumn);
7092 clang_disposeString(EFileName);
7093 }
7094 clang_disposeString(BFileName);
7095 return *this;
7096}
7097
7098Logger &cxindex::Logger::operator<<(CXString Str) {
7099 *this << clang_getCString(Str);
7100 return *this;
7101}
7102
7103Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7104 LogOS << Fmt;
7105 return *this;
7106}
7107
Chandler Carruth37ad2582014-06-27 15:14:39 +00007108static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7109
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007110cxindex::Logger::~Logger() {
7111 LogOS.flush();
7112
Chandler Carruth37ad2582014-06-27 15:14:39 +00007113 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007114
7115 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7116
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007117 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007118 OS << "[libclang:" << Name << ':';
7119
Alp Toker1a86ad22014-07-06 06:24:00 +00007120#ifdef USE_DARWIN_THREADS
7121 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007122 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7123 OS << tid << ':';
7124#endif
7125
7126 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7127 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7128 OS << Msg.str() << '\n';
7129
7130 if (Trace) {
7131 llvm::sys::PrintStackTrace(stderr);
7132 OS << "--------------------------------------------------\n";
7133 }
7134}