blob: 0c1770d1b3e4f944baff177a82bbe7c7287e5183 [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"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000043#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000047#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/MemoryBuffer.h"
49#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
53#include "llvm/Support/Threading.h"
54#include "llvm/Support/Timer.h"
55#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000056
Alp Toker1a86ad22014-07-06 06:24:00 +000057#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
58#define USE_DARWIN_THREADS
59#endif
60
61#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000062#include <pthread.h>
63#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000064
65using namespace clang;
66using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000067using namespace clang::cxtu;
68using namespace clang::cxindex;
69
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000070CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
71 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000072 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000073 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000074 CXTranslationUnit D = new CXTranslationUnitImpl();
75 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000076 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000077 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000078 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000079 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000080 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000081 return D;
82}
83
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000084bool cxtu::isASTReadError(ASTUnit *AU) {
85 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
86 DEnd = AU->stored_diag_end();
87 D != DEnd; ++D) {
88 if (D->getLevel() >= DiagnosticsEngine::Error &&
89 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
90 diag::DiagCat_AST_Deserialization_Issue)
91 return true;
92 }
93 return false;
94}
95
Guy Benyei11169dd2012-12-18 14:30:41 +000096cxtu::CXTUOwner::~CXTUOwner() {
97 if (TU)
98 clang_disposeTranslationUnit(TU);
99}
100
101/// \brief Compare two source ranges to determine their relative position in
102/// the translation unit.
103static RangeComparisonResult RangeCompare(SourceManager &SM,
104 SourceRange R1,
105 SourceRange R2) {
106 assert(R1.isValid() && "First range is invalid?");
107 assert(R2.isValid() && "Second range is invalid?");
108 if (R1.getEnd() != R2.getBegin() &&
109 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
110 return RangeBefore;
111 if (R2.getEnd() != R1.getBegin() &&
112 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
113 return RangeAfter;
114 return RangeOverlap;
115}
116
117/// \brief Determine if a source location falls within, before, or after a
118/// a given source range.
119static RangeComparisonResult LocationCompare(SourceManager &SM,
120 SourceLocation L, SourceRange R) {
121 assert(R.isValid() && "First range is invalid?");
122 assert(L.isValid() && "Second range is invalid?");
123 if (L == R.getBegin() || L == R.getEnd())
124 return RangeOverlap;
125 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
126 return RangeBefore;
127 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
128 return RangeAfter;
129 return RangeOverlap;
130}
131
132/// \brief Translate a Clang source range into a CIndex source range.
133///
134/// Clang internally represents ranges where the end location points to the
135/// start of the token at the end. However, for external clients it is more
136/// useful to have a CXSourceRange be a proper half-open interval. This routine
137/// does the appropriate translation.
138CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
139 const LangOptions &LangOpts,
140 const CharSourceRange &R) {
141 // We want the last character in this location, so we will adjust the
142 // location accordingly.
143 SourceLocation EndLoc = R.getEnd();
144 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
145 EndLoc = SM.getExpansionRange(EndLoc).second;
146 if (R.isTokenRange() && !EndLoc.isInvalid()) {
147 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
148 SM, LangOpts);
149 EndLoc = EndLoc.getLocWithOffset(Length);
150 }
151
Bill Wendlingeade3622013-01-23 08:25:41 +0000152 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000153 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000154 R.getBegin().getRawEncoding(),
155 EndLoc.getRawEncoding()
156 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000157 return Result;
158}
159
160//===----------------------------------------------------------------------===//
161// Cursor visitor.
162//===----------------------------------------------------------------------===//
163
164static SourceRange getRawCursorExtent(CXCursor C);
165static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
166
167
168RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
169 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
170}
171
172/// \brief Visit the given cursor and, if requested by the visitor,
173/// its children.
174///
175/// \param Cursor the cursor to visit.
176///
177/// \param CheckedRegionOfInterest if true, then the caller already checked
178/// that this cursor is within the region of interest.
179///
180/// \returns true if the visitation should be aborted, false if it
181/// should continue.
182bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
183 if (clang_isInvalid(Cursor.kind))
184 return false;
185
186 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000187 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000188 if (!D) {
189 assert(0 && "Invalid declaration cursor");
190 return true; // abort.
191 }
192
193 // Ignore implicit declarations, unless it's an objc method because
194 // currently we should report implicit methods for properties when indexing.
195 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
196 return false;
197 }
198
199 // If we have a range of interest, and this cursor doesn't intersect with it,
200 // we're done.
201 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
202 SourceRange Range = getRawCursorExtent(Cursor);
203 if (Range.isInvalid() || CompareRegionOfInterest(Range))
204 return false;
205 }
206
207 switch (Visitor(Cursor, Parent, ClientData)) {
208 case CXChildVisit_Break:
209 return true;
210
211 case CXChildVisit_Continue:
212 return false;
213
214 case CXChildVisit_Recurse: {
215 bool ret = VisitChildren(Cursor);
216 if (PostChildrenVisitor)
217 if (PostChildrenVisitor(Cursor, ClientData))
218 return true;
219 return ret;
220 }
221 }
222
223 llvm_unreachable("Invalid CXChildVisitResult!");
224}
225
226static bool visitPreprocessedEntitiesInRange(SourceRange R,
227 PreprocessingRecord &PPRec,
228 CursorVisitor &Visitor) {
229 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
230 FileID FID;
231
232 if (!Visitor.shouldVisitIncludedEntities()) {
233 // If the begin/end of the range lie in the same FileID, do the optimization
234 // where we skip preprocessed entities that do not come from the same FileID.
235 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
236 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
237 FID = FileID();
238 }
239
240 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
241 Entities = PPRec.getPreprocessedEntitiesInRange(R);
242 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
243 PPRec, FID);
244}
245
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000246bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000249
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000250 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 SourceManager &SM = Unit->getSourceManager();
252
253 std::pair<FileID, unsigned>
254 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256
257 if (End.first != Begin.first) {
258 // If the end does not reside in the same file, try to recover by
259 // picking the end of the file of begin location.
260 End.first = Begin.first;
261 End.second = SM.getFileIDSize(Begin.first);
262 }
263
264 assert(Begin.first == End.first);
265 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000266 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000267
268 FileID File = Begin.first;
269 unsigned Offset = Begin.second;
270 unsigned Length = End.second - Begin.second;
271
272 if (!VisitDeclsOnly && !VisitPreprocessorLast)
273 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 if (visitDeclsFromFileRegion(File, Offset, Length))
277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
279 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return visitPreprocessedEntitiesInRegion();
281
282 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000283}
284
285static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286 if (!DC)
287 return false;
288
289 for (DeclContext *DeclDC = D->getLexicalDeclContext();
290 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291 if (DeclDC == DC)
292 return true;
293 }
294 return false;
295}
296
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000297bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000299 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 SourceManager &SM = Unit->getSourceManager();
301 SourceRange Range = RegionOfInterest;
302
303 SmallVector<Decl *, 16> Decls;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305
306 // If we didn't find any file level decls for the file, try looking at the
307 // file that it was included from.
308 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309 bool Invalid = false;
310 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000312 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000313
314 SourceLocation Outer;
315 if (SLEntry.isFile())
316 Outer = SLEntry.getFile().getIncludeLoc();
317 else
318 Outer = SLEntry.getExpansion().getExpansionLocStart();
319 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000320 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000321
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000322 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000323 Length = 0;
324 Unit->findFileRegionDecls(File, Offset, Length, Decls);
325 }
326
327 assert(!Decls.empty());
328
329 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000330 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000331 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000333 Decl *D = *DIt;
334 if (D->getSourceRange().isInvalid())
335 continue;
336
337 if (isInLexicalContext(D, CurDC))
338 continue;
339
340 CurDC = dyn_cast<DeclContext>(D);
341
342 if (TagDecl *TD = dyn_cast<TagDecl>(D))
343 if (!TD->isFreeStanding())
344 continue;
345
346 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347 if (CompRes == RangeBefore)
348 continue;
349 if (CompRes == RangeAfter)
350 break;
351
352 assert(CompRes == RangeOverlap);
353 VisitedAtLeastOnce = true;
354
355 if (isa<ObjCContainerDecl>(D)) {
356 FileDI_current = &DIt;
357 FileDE_current = DE;
358 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000359 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000360 }
361
362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000363 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368
369 // No Decls overlapped with the range. Move up the lexical context until there
370 // is a context that contains the range or we reach the translation unit
371 // level.
372 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373 : (*(DIt-1))->getLexicalDeclContext();
374
375 while (DC && !DC->isTranslationUnit()) {
376 Decl *D = cast<Decl>(DC);
377 SourceRange CurDeclRange = D->getSourceRange();
378 if (CurDeclRange.isInvalid())
379 break;
380
381 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000384 }
385
386 DC = D->getLexicalDeclContext();
387 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000388
389 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000390}
391
392bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393 if (!AU->getPreprocessor().getPreprocessingRecord())
394 return false;
395
396 PreprocessingRecord &PPRec
397 = *AU->getPreprocessor().getPreprocessingRecord();
398 SourceManager &SM = AU->getSourceManager();
399
400 if (RegionOfInterest.isValid()) {
401 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402 SourceLocation B = MappedRange.getBegin();
403 SourceLocation E = MappedRange.getEnd();
404
405 if (AU->isInPreambleFileID(B)) {
406 if (SM.isLoadedSourceLocation(E))
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408 PPRec, *this);
409
410 // Beginning of range lies in the preamble but it also extends beyond
411 // it into the main file. Split the range into 2 parts, one covering
412 // the preamble and another covering the main file. This allows subsequent
413 // calls to visitPreprocessedEntitiesInRange to accept a source range that
414 // lies in the same FileID, allowing it to skip preprocessed entities that
415 // do not come from the same FileID.
416 bool breaked =
417 visitPreprocessedEntitiesInRange(
418 SourceRange(B, AU->getEndOfPreambleFileID()),
419 PPRec, *this);
420 if (breaked) return true;
421 return visitPreprocessedEntitiesInRange(
422 SourceRange(AU->getStartOfMainFileID(), E),
423 PPRec, *this);
424 }
425
426 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427 }
428
429 bool OnlyLocalDecls
430 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431
432 if (OnlyLocalDecls)
433 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434 PPRec);
435
436 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437}
438
439template<typename InputIterator>
440bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441 InputIterator Last,
442 PreprocessingRecord &PPRec,
443 FileID FID) {
444 for (; First != Last; ++First) {
445 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446 continue;
447
448 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000449 if (!PPE)
450 continue;
451
Guy Benyei11169dd2012-12-18 14:30:41 +0000452 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453 if (Visit(MakeMacroExpansionCursor(ME, TU)))
454 return true;
455
456 continue;
457 }
458
459 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
460 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461 return true;
462
463 continue;
464 }
465
466 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468 return true;
469
470 continue;
471 }
472 }
473
474 return false;
475}
476
477/// \brief Visit the children of the given cursor.
478///
479/// \returns true if the visitation should be aborted, false if it
480/// should continue.
481bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482 if (clang_isReference(Cursor.kind) &&
483 Cursor.kind != CXCursor_CXXBaseSpecifier) {
484 // By definition, references have no children.
485 return false;
486 }
487
488 // Set the Parent field to Cursor, then back to its old value once we're
489 // done.
490 SetParentRAII SetParent(Parent, StmtParent, Cursor);
491
492 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000493 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 if (!D)
495 return false;
496
497 return VisitAttributes(D) || Visit(D);
498 }
499
500 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000501 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000502 return Visit(S);
503
504 return false;
505 }
506
507 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000508 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000509 return Visit(E);
510
511 return false;
512 }
513
514 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000515 CXTranslationUnit TU = getCursorTU(Cursor);
516 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000517
518 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519 for (unsigned I = 0; I != 2; ++I) {
520 if (VisitOrder[I]) {
521 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522 RegionOfInterest.isInvalid()) {
523 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524 TLEnd = CXXUnit->top_level_end();
525 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000526 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000527 return true;
528 }
529 } else if (VisitDeclContext(
530 CXXUnit->getASTContext().getTranslationUnitDecl()))
531 return true;
532 continue;
533 }
534
535 // Walk the preprocessing record.
536 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
537 visitPreprocessedEntitiesInRegion();
538 }
539
540 return false;
541 }
542
543 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000544 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000545 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
546 return Visit(BaseTSInfo->getTypeLoc());
547 }
548 }
549 }
550
551 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000552 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000554 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000555 return Visit(cxcursor::MakeCursorObjCClassRef(
556 ObjT->getInterface(),
557 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000558 }
559
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000560 // If pointing inside a macro definition, check if the token is an identifier
561 // that was ever defined as a macro. In such a case, create a "pseudo" macro
562 // expansion cursor for that token.
563 SourceLocation BeginLoc = RegionOfInterest.getBegin();
564 if (Cursor.kind == CXCursor_MacroDefinition &&
565 BeginLoc == RegionOfInterest.getEnd()) {
566 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000567 const MacroInfo *MI =
568 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000569 if (MacroDefinition *MacroDef =
570 checkForMacroInMacroDefinition(MI, Loc, TU))
571 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
572 }
573
Guy Benyei11169dd2012-12-18 14:30:41 +0000574 // Nothing to visit at the moment.
575 return false;
576}
577
578bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
579 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
580 if (Visit(TSInfo->getTypeLoc()))
581 return true;
582
583 if (Stmt *Body = B->getBody())
584 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
585
586 return false;
587}
588
Ted Kremenek03325582013-02-21 01:29:01 +0000589Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000590 if (RegionOfInterest.isValid()) {
591 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
592 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 switch (CompareRegionOfInterest(Range)) {
596 case RangeBefore:
597 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000598 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000599
600 case RangeAfter:
601 // This declaration comes after the region of interest; we're done.
602 return false;
603
604 case RangeOverlap:
605 // This declaration overlaps the region of interest; visit it.
606 break;
607 }
608 }
609 return true;
610}
611
612bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
613 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
614
615 // FIXME: Eventually remove. This part of a hack to support proper
616 // iteration over all Decls contained lexically within an ObjC container.
617 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
618 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
619
620 for ( ; I != E; ++I) {
621 Decl *D = *I;
622 if (D->getLexicalDeclContext() != DC)
623 continue;
624 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
625
626 // Ignore synthesized ivars here, otherwise if we have something like:
627 // @synthesize prop = _prop;
628 // and '_prop' is not declared, we will encounter a '_prop' ivar before
629 // encountering the 'prop' synthesize declaration and we will think that
630 // we passed the region-of-interest.
631 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
632 if (ivarD->getSynthesize())
633 continue;
634 }
635
636 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
637 // declarations is a mismatch with the compiler semantics.
638 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
639 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
640 if (!ID->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
642
643 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
644 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
645 if (!PD->isThisDeclarationADefinition())
646 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
647 }
648
Ted Kremenek03325582013-02-21 01:29:01 +0000649 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000650 if (!V.hasValue())
651 continue;
652 if (!V.getValue())
653 return false;
654 if (Visit(Cursor, true))
655 return true;
656 }
657 return false;
658}
659
660bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
661 llvm_unreachable("Translation units are visited directly by Visit()");
662}
663
664bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
665 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
666 return Visit(TSInfo->getTypeLoc());
667
668 return false;
669}
670
671bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
672 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
673 return Visit(TSInfo->getTypeLoc());
674
675 return false;
676}
677
678bool CursorVisitor::VisitTagDecl(TagDecl *D) {
679 return VisitDeclContext(D);
680}
681
682bool CursorVisitor::VisitClassTemplateSpecializationDecl(
683 ClassTemplateSpecializationDecl *D) {
684 bool ShouldVisitBody = false;
685 switch (D->getSpecializationKind()) {
686 case TSK_Undeclared:
687 case TSK_ImplicitInstantiation:
688 // Nothing to visit
689 return false;
690
691 case TSK_ExplicitInstantiationDeclaration:
692 case TSK_ExplicitInstantiationDefinition:
693 break;
694
695 case TSK_ExplicitSpecialization:
696 ShouldVisitBody = true;
697 break;
698 }
699
700 // Visit the template arguments used in the specialization.
701 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
702 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000703 if (TemplateSpecializationTypeLoc TSTLoc =
704 TL.getAs<TemplateSpecializationTypeLoc>()) {
705 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
706 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000707 return true;
708 }
709 }
710
711 if (ShouldVisitBody && VisitCXXRecordDecl(D))
712 return true;
713
714 return false;
715}
716
717bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
718 ClassTemplatePartialSpecializationDecl *D) {
719 // FIXME: Visit the "outer" template parameter lists on the TagDecl
720 // before visiting these template parameters.
721 if (VisitTemplateParameters(D->getTemplateParameters()))
722 return true;
723
724 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000725 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
726 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
727 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000728 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
729 return true;
730
731 return VisitCXXRecordDecl(D);
732}
733
734bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
735 // Visit the default argument.
736 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
737 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
738 if (Visit(DefArg->getTypeLoc()))
739 return true;
740
741 return false;
742}
743
744bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
745 if (Expr *Init = D->getInitExpr())
746 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
747 return false;
748}
749
750bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000751 unsigned NumParamList = DD->getNumTemplateParameterLists();
752 for (unsigned i = 0; i < NumParamList; i++) {
753 TemplateParameterList* Params = DD->getTemplateParameterList(i);
754 if (VisitTemplateParameters(Params))
755 return true;
756 }
757
Guy Benyei11169dd2012-12-18 14:30:41 +0000758 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
759 if (Visit(TSInfo->getTypeLoc()))
760 return true;
761
762 // Visit the nested-name-specifier, if present.
763 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
764 if (VisitNestedNameSpecifierLoc(QualifierLoc))
765 return true;
766
767 return false;
768}
769
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000770/// \brief Compare two base or member initializers based on their source order.
771static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
772 CXXCtorInitializer *const *Y) {
773 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
774}
775
Guy Benyei11169dd2012-12-18 14:30:41 +0000776bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000777 unsigned NumParamList = ND->getNumTemplateParameterLists();
778 for (unsigned i = 0; i < NumParamList; i++) {
779 TemplateParameterList* Params = ND->getTemplateParameterList(i);
780 if (VisitTemplateParameters(Params))
781 return true;
782 }
783
Guy Benyei11169dd2012-12-18 14:30:41 +0000784 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
785 // Visit the function declaration's syntactic components in the order
786 // written. This requires a bit of work.
787 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000788 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000789
790 // If we have a function declared directly (without the use of a typedef),
791 // visit just the return type. Otherwise, just visit the function's type
792 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000793 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 (!FTL && Visit(TL)))
795 return true;
796
797 // Visit the nested-name-specifier, if present.
798 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
799 if (VisitNestedNameSpecifierLoc(QualifierLoc))
800 return true;
801
802 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000803 if (!isa<CXXDestructorDecl>(ND))
804 if (VisitDeclarationNameInfo(ND->getNameInfo()))
805 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000806
807 // FIXME: Visit explicitly-specified template arguments!
808
809 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000810 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000811 return true;
812
Bill Wendling44426052012-12-20 19:22:21 +0000813 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 }
815
816 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
817 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
818 // Find the initializers that were written in the source.
819 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000820 for (auto *I : Constructor->inits()) {
821 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000822 continue;
823
Aaron Ballman0ad78302014-03-13 17:34:31 +0000824 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 }
826
827 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000828 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
829 &CompareCXXCtorInitializers);
830
Guy Benyei11169dd2012-12-18 14:30:41 +0000831 // Visit the initializers in source order
832 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
833 CXXCtorInitializer *Init = WrittenInits[I];
834 if (Init->isAnyMemberInitializer()) {
835 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
836 Init->getMemberLocation(), TU)))
837 return true;
838 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
839 if (Visit(TInfo->getTypeLoc()))
840 return true;
841 }
842
843 // Visit the initializer value.
844 if (Expr *Initializer = Init->getInit())
845 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
846 return true;
847 }
848 }
849
850 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
851 return true;
852 }
853
854 return false;
855}
856
857bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
858 if (VisitDeclaratorDecl(D))
859 return true;
860
861 if (Expr *BitWidth = D->getBitWidth())
862 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
863
864 return false;
865}
866
867bool CursorVisitor::VisitVarDecl(VarDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *Init = D->getInit())
872 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
882 if (Expr *DefArg = D->getDefaultArgument())
883 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
884
885 return false;
886}
887
888bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
889 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
890 // before visiting these template parameters.
891 if (VisitTemplateParameters(D->getTemplateParameters()))
892 return true;
893
894 return VisitFunctionDecl(D->getTemplatedDecl());
895}
896
897bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
898 // FIXME: Visit the "outer" template parameter lists on the TagDecl
899 // before visiting these template parameters.
900 if (VisitTemplateParameters(D->getTemplateParameters()))
901 return true;
902
903 return VisitCXXRecordDecl(D->getTemplatedDecl());
904}
905
906bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
907 if (VisitTemplateParameters(D->getTemplateParameters()))
908 return true;
909
910 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
911 VisitTemplateArgumentLoc(D->getDefaultArgument()))
912 return true;
913
914 return false;
915}
916
917bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000918 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 if (Visit(TSInfo->getTypeLoc()))
920 return true;
921
Aaron Ballman43b68be2014-03-07 17:50:17 +0000922 for (const auto *P : ND->params()) {
923 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000924 return true;
925 }
926
927 if (ND->isThisDeclarationADefinition() &&
928 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
929 return true;
930
931 return false;
932}
933
934template <typename DeclIt>
935static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
936 SourceManager &SM, SourceLocation EndLoc,
937 SmallVectorImpl<Decl *> &Decls) {
938 DeclIt next = *DI_current;
939 while (++next != DE_current) {
940 Decl *D_next = *next;
941 if (!D_next)
942 break;
943 SourceLocation L = D_next->getLocStart();
944 if (!L.isValid())
945 break;
946 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
947 *DI_current = next;
948 Decls.push_back(D_next);
949 continue;
950 }
951 break;
952 }
953}
954
Guy Benyei11169dd2012-12-18 14:30:41 +0000955bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
956 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
957 // an @implementation can lexically contain Decls that are not properly
958 // nested in the AST. When we identify such cases, we need to retrofit
959 // this nesting here.
960 if (!DI_current && !FileDI_current)
961 return VisitDeclContext(D);
962
963 // Scan the Decls that immediately come after the container
964 // in the current DeclContext. If any fall within the
965 // container's lexical region, stash them into a vector
966 // for later processing.
967 SmallVector<Decl *, 24> DeclsInContainer;
968 SourceLocation EndLoc = D->getSourceRange().getEnd();
969 SourceManager &SM = AU->getSourceManager();
970 if (EndLoc.isValid()) {
971 if (DI_current) {
972 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
973 DeclsInContainer);
974 } else {
975 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
976 DeclsInContainer);
977 }
978 }
979
980 // The common case.
981 if (DeclsInContainer.empty())
982 return VisitDeclContext(D);
983
984 // Get all the Decls in the DeclContext, and sort them with the
985 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000986 for (auto *SubDecl : D->decls()) {
987 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
988 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000989 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000990 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 }
992
993 // Now sort the Decls so that they appear in lexical order.
994 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000995 [&SM](Decl *A, Decl *B) {
996 SourceLocation L_A = A->getLocStart();
997 SourceLocation L_B = B->getLocStart();
998 assert(L_A.isValid() && L_B.isValid());
999 return SM.isBeforeInTranslationUnit(L_A, L_B);
1000 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001001
1002 // Now visit the decls.
1003 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1004 E = DeclsInContainer.end(); I != E; ++I) {
1005 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001006 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 if (!V.hasValue())
1008 continue;
1009 if (!V.getValue())
1010 return false;
1011 if (Visit(Cursor, true))
1012 return true;
1013 }
1014 return false;
1015}
1016
1017bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1018 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1019 TU)))
1020 return true;
1021
1022 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1023 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1024 E = ND->protocol_end(); I != E; ++I, ++PL)
1025 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1026 return true;
1027
1028 return VisitObjCContainerDecl(ND);
1029}
1030
1031bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1032 if (!PID->isThisDeclarationADefinition())
1033 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1034
1035 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1036 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1037 E = PID->protocol_end(); I != E; ++I, ++PL)
1038 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1039 return true;
1040
1041 return VisitObjCContainerDecl(PID);
1042}
1043
1044bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1045 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1046 return true;
1047
1048 // FIXME: This implements a workaround with @property declarations also being
1049 // installed in the DeclContext for the @interface. Eventually this code
1050 // should be removed.
1051 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1052 if (!CDecl || !CDecl->IsClassExtension())
1053 return false;
1054
1055 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1056 if (!ID)
1057 return false;
1058
1059 IdentifierInfo *PropertyId = PD->getIdentifier();
1060 ObjCPropertyDecl *prevDecl =
1061 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1062
1063 if (!prevDecl)
1064 return false;
1065
1066 // Visit synthesized methods since they will be skipped when visiting
1067 // the @interface.
1068 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1074 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1075 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1076 return true;
1077
1078 return false;
1079}
1080
1081bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1082 if (!D->isThisDeclarationADefinition()) {
1083 // Forward declaration is treated like a reference.
1084 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1085 }
1086
1087 // Issue callbacks for super class.
1088 if (D->getSuperClass() &&
1089 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1090 D->getSuperClassLoc(),
1091 TU)))
1092 return true;
1093
1094 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1095 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1096 E = D->protocol_end(); I != E; ++I, ++PL)
1097 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1098 return true;
1099
1100 return VisitObjCContainerDecl(D);
1101}
1102
1103bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1104 return VisitObjCContainerDecl(D);
1105}
1106
1107bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1108 // 'ID' could be null when dealing with invalid code.
1109 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1110 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1111 return true;
1112
1113 return VisitObjCImplDecl(D);
1114}
1115
1116bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1117#if 0
1118 // Issue callbacks for super class.
1119 // FIXME: No source location information!
1120 if (D->getSuperClass() &&
1121 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1122 D->getSuperClassLoc(),
1123 TU)))
1124 return true;
1125#endif
1126
1127 return VisitObjCImplDecl(D);
1128}
1129
1130bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1131 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1132 if (PD->isIvarNameSpecified())
1133 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1134
1135 return false;
1136}
1137
1138bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1139 return VisitDeclContext(D);
1140}
1141
1142bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1143 // Visit nested-name-specifier.
1144 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1145 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1146 return true;
1147
1148 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1149 D->getTargetNameLoc(), TU));
1150}
1151
1152bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1153 // Visit nested-name-specifier.
1154 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1155 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1156 return true;
1157 }
1158
1159 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1160 return true;
1161
1162 return VisitDeclarationNameInfo(D->getNameInfo());
1163}
1164
1165bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1166 // Visit nested-name-specifier.
1167 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1168 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1169 return true;
1170
1171 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1172 D->getIdentLocation(), TU));
1173}
1174
1175bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1176 // Visit nested-name-specifier.
1177 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1178 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1179 return true;
1180 }
1181
1182 return VisitDeclarationNameInfo(D->getNameInfo());
1183}
1184
1185bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1186 UnresolvedUsingTypenameDecl *D) {
1187 // Visit nested-name-specifier.
1188 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1189 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1190 return true;
1191
1192 return false;
1193}
1194
1195bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1196 switch (Name.getName().getNameKind()) {
1197 case clang::DeclarationName::Identifier:
1198 case clang::DeclarationName::CXXLiteralOperatorName:
1199 case clang::DeclarationName::CXXOperatorName:
1200 case clang::DeclarationName::CXXUsingDirective:
1201 return false;
1202
1203 case clang::DeclarationName::CXXConstructorName:
1204 case clang::DeclarationName::CXXDestructorName:
1205 case clang::DeclarationName::CXXConversionFunctionName:
1206 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1207 return Visit(TSInfo->getTypeLoc());
1208 return false;
1209
1210 case clang::DeclarationName::ObjCZeroArgSelector:
1211 case clang::DeclarationName::ObjCOneArgSelector:
1212 case clang::DeclarationName::ObjCMultiArgSelector:
1213 // FIXME: Per-identifier location info?
1214 return false;
1215 }
1216
1217 llvm_unreachable("Invalid DeclarationName::Kind!");
1218}
1219
1220bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1221 SourceRange Range) {
1222 // FIXME: This whole routine is a hack to work around the lack of proper
1223 // source information in nested-name-specifiers (PR5791). Since we do have
1224 // a beginning source location, we can visit the first component of the
1225 // nested-name-specifier, if it's a single-token component.
1226 if (!NNS)
1227 return false;
1228
1229 // Get the first component in the nested-name-specifier.
1230 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1231 NNS = Prefix;
1232
1233 switch (NNS->getKind()) {
1234 case NestedNameSpecifier::Namespace:
1235 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1236 TU));
1237
1238 case NestedNameSpecifier::NamespaceAlias:
1239 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1240 Range.getBegin(), TU));
1241
1242 case NestedNameSpecifier::TypeSpec: {
1243 // If the type has a form where we know that the beginning of the source
1244 // range matches up with a reference cursor. Visit the appropriate reference
1245 // cursor.
1246 const Type *T = NNS->getAsType();
1247 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1248 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1249 if (const TagType *Tag = dyn_cast<TagType>(T))
1250 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1251 if (const TemplateSpecializationType *TST
1252 = dyn_cast<TemplateSpecializationType>(T))
1253 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1254 break;
1255 }
1256
1257 case NestedNameSpecifier::TypeSpecWithTemplate:
1258 case NestedNameSpecifier::Global:
1259 case NestedNameSpecifier::Identifier:
1260 break;
1261 }
1262
1263 return false;
1264}
1265
1266bool
1267CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1268 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1269 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1270 Qualifiers.push_back(Qualifier);
1271
1272 while (!Qualifiers.empty()) {
1273 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1274 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1275 switch (NNS->getKind()) {
1276 case NestedNameSpecifier::Namespace:
1277 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1278 Q.getLocalBeginLoc(),
1279 TU)))
1280 return true;
1281
1282 break;
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Q.getLocalBeginLoc(),
1287 TU)))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::TypeSpec:
1293 case NestedNameSpecifier::TypeSpecWithTemplate:
1294 if (Visit(Q.getTypeLoc()))
1295 return true;
1296
1297 break;
1298
1299 case NestedNameSpecifier::Global:
1300 case NestedNameSpecifier::Identifier:
1301 break;
1302 }
1303 }
1304
1305 return false;
1306}
1307
1308bool CursorVisitor::VisitTemplateParameters(
1309 const TemplateParameterList *Params) {
1310 if (!Params)
1311 return false;
1312
1313 for (TemplateParameterList::const_iterator P = Params->begin(),
1314 PEnd = Params->end();
1315 P != PEnd; ++P) {
1316 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1317 return true;
1318 }
1319
1320 return false;
1321}
1322
1323bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1324 switch (Name.getKind()) {
1325 case TemplateName::Template:
1326 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1327
1328 case TemplateName::OverloadedTemplate:
1329 // Visit the overloaded template set.
1330 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1331 return true;
1332
1333 return false;
1334
1335 case TemplateName::DependentTemplate:
1336 // FIXME: Visit nested-name-specifier.
1337 return false;
1338
1339 case TemplateName::QualifiedTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsQualifiedTemplateName()->getDecl(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParm:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParmPack:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1353 Loc, TU));
1354 }
1355
1356 llvm_unreachable("Invalid TemplateName::Kind!");
1357}
1358
1359bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1360 switch (TAL.getArgument().getKind()) {
1361 case TemplateArgument::Null:
1362 case TemplateArgument::Integral:
1363 case TemplateArgument::Pack:
1364 return false;
1365
1366 case TemplateArgument::Type:
1367 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1368 return Visit(TSInfo->getTypeLoc());
1369 return false;
1370
1371 case TemplateArgument::Declaration:
1372 if (Expr *E = TAL.getSourceDeclExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::NullPtr:
1377 if (Expr *E = TAL.getSourceNullPtrExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Expression:
1382 if (Expr *E = TAL.getSourceExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Template:
1387 case TemplateArgument::TemplateExpansion:
1388 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1389 return true;
1390
1391 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1392 TAL.getTemplateNameLoc());
1393 }
1394
1395 llvm_unreachable("Invalid TemplateArgument::Kind!");
1396}
1397
1398bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1399 return VisitDeclContext(D);
1400}
1401
1402bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1403 return Visit(TL.getUnqualifiedLoc());
1404}
1405
1406bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1407 ASTContext &Context = AU->getASTContext();
1408
1409 // Some builtin types (such as Objective-C's "id", "sel", and
1410 // "Class") have associated declarations. Create cursors for those.
1411 QualType VisitType;
1412 switch (TL.getTypePtr()->getKind()) {
1413
1414 case BuiltinType::Void:
1415 case BuiltinType::NullPtr:
1416 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001417 case BuiltinType::OCLImage1d:
1418 case BuiltinType::OCLImage1dArray:
1419 case BuiltinType::OCLImage1dBuffer:
1420 case BuiltinType::OCLImage2d:
1421 case BuiltinType::OCLImage2dArray:
1422 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001423 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001424 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001425#define BUILTIN_TYPE(Id, SingletonId)
1426#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#include "clang/AST/BuiltinTypes.def"
1431 break;
1432
1433 case BuiltinType::ObjCId:
1434 VisitType = Context.getObjCIdType();
1435 break;
1436
1437 case BuiltinType::ObjCClass:
1438 VisitType = Context.getObjCClassType();
1439 break;
1440
1441 case BuiltinType::ObjCSel:
1442 VisitType = Context.getObjCSelType();
1443 break;
1444 }
1445
1446 if (!VisitType.isNull()) {
1447 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1448 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1449 TU));
1450 }
1451
1452 return false;
1453}
1454
1455bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1456 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1457}
1458
1459bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1464 if (TL.isDefinition())
1465 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1466
1467 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1468}
1469
1470bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1475 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1476 return true;
1477
1478 return false;
1479}
1480
1481bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1482 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1483 return true;
1484
1485 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1486 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1487 TU)))
1488 return true;
1489 }
1490
1491 return false;
1492}
1493
1494bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1499 return Visit(TL.getInnerLoc());
1500}
1501
1502bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1503 return Visit(TL.getPointeeLoc());
1504}
1505
1506bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1523 return Visit(TL.getModifiedLoc());
1524}
1525
1526bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1527 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001528 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001529 return true;
1530
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001531 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1532 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1534 return true;
1535
1536 return false;
1537}
1538
1539bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1540 if (Visit(TL.getElementLoc()))
1541 return true;
1542
1543 if (Expr *Size = TL.getSizeExpr())
1544 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1545
1546 return false;
1547}
1548
Reid Kleckner8a365022013-06-24 17:51:48 +00001549bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1550 return Visit(TL.getOriginalLoc());
1551}
1552
Reid Kleckner0503a872013-12-05 01:23:43 +00001553bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Guy Benyei11169dd2012-12-18 14:30:41 +00001557bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1558 TemplateSpecializationTypeLoc TL) {
1559 // Visit the template name.
1560 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1561 TL.getTemplateNameLoc()))
1562 return true;
1563
1564 // Visit the template arguments.
1565 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1566 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1567 return true;
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1573 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1574}
1575
1576bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1577 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1578 return Visit(TSInfo->getTypeLoc());
1579
1580 return false;
1581}
1582
1583bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1584 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1585 return Visit(TSInfo->getTypeLoc());
1586
1587 return false;
1588}
1589
1590bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1591 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1592 return true;
1593
1594 return false;
1595}
1596
1597bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1598 DependentTemplateSpecializationTypeLoc TL) {
1599 // Visit the nested-name-specifier, if there is one.
1600 if (TL.getQualifierLoc() &&
1601 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1602 return true;
1603
1604 // Visit the template arguments.
1605 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1606 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1607 return true;
1608
1609 return false;
1610}
1611
1612bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1613 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1614 return true;
1615
1616 return Visit(TL.getNamedTypeLoc());
1617}
1618
1619bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1620 return Visit(TL.getPatternLoc());
1621}
1622
1623bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1624 if (Expr *E = TL.getUnderlyingExpr())
1625 return Visit(MakeCXCursor(E, StmtParent, TU));
1626
1627 return false;
1628}
1629
1630bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1631 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1632}
1633
1634bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1635 return Visit(TL.getValueLoc());
1636}
1637
1638#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1639bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1640 return Visit##PARENT##Loc(TL); \
1641}
1642
1643DEFAULT_TYPELOC_IMPL(Complex, Type)
1644DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1649DEFAULT_TYPELOC_IMPL(Vector, Type)
1650DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1651DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1653DEFAULT_TYPELOC_IMPL(Record, TagType)
1654DEFAULT_TYPELOC_IMPL(Enum, TagType)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1656DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1657DEFAULT_TYPELOC_IMPL(Auto, Type)
1658
1659bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1660 // Visit the nested-name-specifier, if present.
1661 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1662 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1663 return true;
1664
1665 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001666 for (const auto &I : D->bases()) {
1667 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001668 return true;
1669 }
1670 }
1671
1672 return VisitTagDecl(D);
1673}
1674
1675bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001676 for (const auto *I : D->attrs())
1677 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001678 return true;
1679
1680 return false;
1681}
1682
1683//===----------------------------------------------------------------------===//
1684// Data-recursive visitor methods.
1685//===----------------------------------------------------------------------===//
1686
1687namespace {
1688#define DEF_JOB(NAME, DATA, KIND)\
1689class NAME : public VisitorJob {\
1690public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001691 NAME(const DATA *d, CXCursor parent) : \
1692 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001693 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001695};
1696
1697DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1698DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1699DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1700DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1701DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1702 ExplicitTemplateArgsVisitKind)
1703DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1704DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1705DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1706#undef DEF_JOB
1707
1708class DeclVisit : public VisitorJob {
1709public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001712 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001713 static bool classof(const VisitorJob *VJ) {
1714 return VJ->getKind() == DeclVisitKind;
1715 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001716 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 bool isFirst() const { return data[1] ? true : false; }
1718};
1719class TypeLocVisit : public VisitorJob {
1720public:
1721 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1722 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1723 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1724
1725 static bool classof(const VisitorJob *VJ) {
1726 return VJ->getKind() == TypeLocVisitKind;
1727 }
1728
1729 TypeLoc get() const {
1730 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001731 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001732 }
1733};
1734
1735class LabelRefVisit : public VisitorJob {
1736public:
1737 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1738 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1739 labelLoc.getPtrEncoding()) {}
1740
1741 static bool classof(const VisitorJob *VJ) {
1742 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1743 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 const LabelDecl *get() const {
1745 return static_cast<const LabelDecl *>(data[0]);
1746 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001747 SourceLocation getLoc() const {
1748 return SourceLocation::getFromPtrEncoding(data[1]); }
1749};
1750
1751class NestedNameSpecifierLocVisit : public VisitorJob {
1752public:
1753 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1754 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1755 Qualifier.getNestedNameSpecifier(),
1756 Qualifier.getOpaqueData()) { }
1757
1758 static bool classof(const VisitorJob *VJ) {
1759 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1760 }
1761
1762 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001763 return NestedNameSpecifierLoc(
1764 const_cast<NestedNameSpecifier *>(
1765 static_cast<const NestedNameSpecifier *>(data[0])),
1766 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001767 }
1768};
1769
1770class DeclarationNameInfoVisit : public VisitorJob {
1771public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001773 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 static bool classof(const VisitorJob *VJ) {
1775 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1776 }
1777 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001778 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001779 switch (S->getStmtClass()) {
1780 default:
1781 llvm_unreachable("Unhandled Stmt");
1782 case clang::Stmt::MSDependentExistsStmtClass:
1783 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1784 case Stmt::CXXDependentScopeMemberExprClass:
1785 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1786 case Stmt::DependentScopeDeclRefExprClass:
1787 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001788 case Stmt::OMPCriticalDirectiveClass:
1789 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001790 }
1791 }
1792};
1793class MemberRefVisit : public VisitorJob {
1794public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001795 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1797 L.getPtrEncoding()) {}
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const FieldDecl *get() const {
1802 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 }
1804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1806 }
1807};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001809 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001810 VisitorWorkList &WL;
1811 CXCursor Parent;
1812public:
1813 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1814 : WL(wl), Parent(parent) {}
1815
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001816 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1817 void VisitBlockExpr(const BlockExpr *B);
1818 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1819 void VisitCompoundStmt(const CompoundStmt *S);
1820 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1821 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1822 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1823 void VisitCXXNewExpr(const CXXNewExpr *E);
1824 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1825 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1826 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1827 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1828 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1829 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1830 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1831 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1832 void VisitDeclRefExpr(const DeclRefExpr *D);
1833 void VisitDeclStmt(const DeclStmt *S);
1834 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1835 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1836 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1837 void VisitForStmt(const ForStmt *FS);
1838 void VisitGotoStmt(const GotoStmt *GS);
1839 void VisitIfStmt(const IfStmt *If);
1840 void VisitInitListExpr(const InitListExpr *IE);
1841 void VisitMemberExpr(const MemberExpr *M);
1842 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1843 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1844 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1845 void VisitOverloadExpr(const OverloadExpr *E);
1846 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1847 void VisitStmt(const Stmt *S);
1848 void VisitSwitchStmt(const SwitchStmt *S);
1849 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001850 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1851 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1852 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1853 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1854 void VisitVAArgExpr(const VAArgExpr *E);
1855 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1856 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1857 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1858 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001859 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1860 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001861 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001862 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001863 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001864 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001865 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001866 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001867 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001868 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001869 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001870 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001871 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001872 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001873 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001874 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001875 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001876 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877
Guy Benyei11169dd2012-12-18 14:30:41 +00001878private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1881 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1883 void AddStmt(const Stmt *S);
1884 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001887 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001888};
1889} // end anonyous namespace
1890
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001892 // 'S' should always be non-null, since it comes from the
1893 // statement we are visiting.
1894 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1895}
1896
1897void
1898EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1899 if (Qualifier)
1900 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1901}
1902
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 if (S)
1905 WL.push_back(StmtVisit(S, Parent));
1906}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 if (D)
1909 WL.push_back(DeclVisit(D, Parent, isFirst));
1910}
1911void EnqueueVisitor::
1912 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1913 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001915}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001916void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 if (D)
1918 WL.push_back(MemberRefVisit(D, L, Parent));
1919}
1920void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1921 if (TI)
1922 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1923 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001925 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 AddStmt(*Child);
1928 }
1929 if (size == WL.size())
1930 return;
1931 // Now reverse the entries we just added. This will match the DFS
1932 // ordering performed by the worklist.
1933 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1934 std::reverse(I, E);
1935}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001936namespace {
1937class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1938 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001939 /// \brief Process clauses with list of variables.
1940 template <typename T>
1941 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942public:
1943 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1944#define OPENMP_CLAUSE(Name, Class) \
1945 void Visit##Class(const Class *C);
1946#include "clang/Basic/OpenMPKinds.def"
1947};
1948
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001949void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1950 Visitor->AddStmt(C->getCondition());
1951}
1952
Alexey Bataev3778b602014-07-17 07:32:53 +00001953void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1954 Visitor->AddStmt(C->getCondition());
1955}
1956
Alexey Bataev568a8332014-03-06 06:15:19 +00001957void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1958 Visitor->AddStmt(C->getNumThreads());
1959}
1960
Alexey Bataev62c87d22014-03-21 04:51:18 +00001961void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1962 Visitor->AddStmt(C->getSafelen());
1963}
1964
Alexander Musman8bd31e62014-05-27 15:12:19 +00001965void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1966 Visitor->AddStmt(C->getNumForLoops());
1967}
1968
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001969void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001970
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001971void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1972
Alexey Bataev56dafe82014-06-20 07:16:17 +00001973void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1974 Visitor->AddStmt(C->getChunkSize());
1975}
1976
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001977void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1978
Alexey Bataev236070f2014-06-20 11:19:47 +00001979void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1980
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001981void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1982
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001983void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1984
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001985void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1986
Alexey Bataevdea47612014-07-23 07:46:59 +00001987void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1988
Alexey Bataev67a4f222014-07-23 10:25:33 +00001989void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1990
Alexey Bataev459dec02014-07-24 06:46:57 +00001991void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1992
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001993void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1994
Alexey Bataev756c1962013-09-24 03:17:45 +00001995template<typename T>
1996void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001997 for (const auto *I : Node->varlists())
1998 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001999}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002000
2001void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002002 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002004void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2005 const OMPFirstprivateClause *C) {
2006 VisitOMPClauseList(C);
2007}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002008void OMPClauseEnqueue::VisitOMPLastprivateClause(
2009 const OMPLastprivateClause *C) {
2010 VisitOMPClauseList(C);
2011}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002012void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002014}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002015void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2016 VisitOMPClauseList(C);
2017}
Alexander Musman8dba6642014-04-22 13:09:42 +00002018void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2019 VisitOMPClauseList(C);
2020 Visitor->AddStmt(C->getStep());
2021}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002022void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2023 VisitOMPClauseList(C);
2024 Visitor->AddStmt(C->getAlignment());
2025}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002026void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2027 VisitOMPClauseList(C);
2028}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002029void
2030OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2031 VisitOMPClauseList(C);
2032}
Alexey Bataev6125da92014-07-21 11:26:11 +00002033void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2034 VisitOMPClauseList(C);
2035}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002036}
Alexey Bataev756c1962013-09-24 03:17:45 +00002037
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002038void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2039 unsigned size = WL.size();
2040 OMPClauseEnqueue Visitor(this);
2041 Visitor.Visit(S);
2042 if (size == WL.size())
2043 return;
2044 // Now reverse the entries we just added. This will match the DFS
2045 // ordering performed by the worklist.
2046 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2047 std::reverse(I, E);
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 AddDecl(B->getBlockDecl());
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 AddTypeLoc(E->getTypeSourceInfo());
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2060 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 E = S->body_rend(); I != E; ++I) {
2062 AddStmt(*I);
2063 }
2064}
2065void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 AddStmt(S->getSubStmt());
2068 AddDeclarationNameInfo(S);
2069 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2070 AddNestedNameSpecifierLoc(QualifierLoc);
2071}
2072
2073void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2076 AddDeclarationNameInfo(E);
2077 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2078 AddNestedNameSpecifierLoc(QualifierLoc);
2079 if (!E->isImplicitAccess())
2080 AddStmt(E->getBase());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 // Enqueue the initializer , if any.
2084 AddStmt(E->getInitializer());
2085 // Enqueue the array size, if any.
2086 AddStmt(E->getArraySize());
2087 // Enqueue the allocated type.
2088 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2089 // Enqueue the placement arguments.
2090 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2091 AddStmt(E->getPlacementArg(I-1));
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2095 AddStmt(CE->getArg(I-1));
2096 AddStmt(CE->getCallee());
2097 AddStmt(CE->getArg(0));
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2100 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 // Visit the name of the type being destroyed.
2102 AddTypeLoc(E->getDestroyedTypeInfo());
2103 // Visit the scope type that looks disturbingly like the nested-name-specifier
2104 // but isn't.
2105 AddTypeLoc(E->getScopeTypeInfo());
2106 // Visit the nested-name-specifier.
2107 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2108 AddNestedNameSpecifierLoc(QualifierLoc);
2109 // Visit base expression.
2110 AddStmt(E->getBase());
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2113 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 AddTypeLoc(E->getTypeSourceInfo());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2117 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 EnqueueChildren(E);
2119 AddTypeLoc(E->getTypeSourceInfo());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 EnqueueChildren(E);
2123 if (E->isTypeOperand())
2124 AddTypeLoc(E->getTypeOperandSourceInfo());
2125}
2126
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2128 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 EnqueueChildren(E);
2130 AddTypeLoc(E->getTypeSourceInfo());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 EnqueueChildren(E);
2134 if (E->isTypeOperand())
2135 AddTypeLoc(E->getTypeOperandSourceInfo());
2136}
2137
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 EnqueueChildren(S);
2140 AddDecl(S->getExceptionDecl());
2141}
2142
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 if (DR->hasExplicitTemplateArgs()) {
2145 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2146 }
2147 WL.push_back(DeclRefExprParts(DR, Parent));
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2150 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2152 AddDeclarationNameInfo(E);
2153 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 unsigned size = WL.size();
2157 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002158 for (const auto *D : S->decls()) {
2159 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 isFirst = false;
2161 }
2162 if (size == WL.size())
2163 return;
2164 // Now reverse the entries we just added. This will match the DFS
2165 // ordering performed by the worklist.
2166 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2167 std::reverse(I, E);
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 D = E->designators_rbegin(), DEnd = E->designators_rend();
2173 D != DEnd; ++D) {
2174 if (D->isFieldDesignator()) {
2175 if (FieldDecl *Field = D->getField())
2176 AddMemberRef(Field, D->getFieldLoc());
2177 continue;
2178 }
2179 if (D->isArrayDesignator()) {
2180 AddStmt(E->getArrayIndex(*D));
2181 continue;
2182 }
2183 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2184 AddStmt(E->getArrayRangeEnd(*D));
2185 AddStmt(E->getArrayRangeStart(*D));
2186 }
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(E);
2190 AddTypeLoc(E->getTypeInfoAsWritten());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddStmt(FS->getBody());
2194 AddStmt(FS->getInc());
2195 AddStmt(FS->getCond());
2196 AddDecl(FS->getConditionVariable());
2197 AddStmt(FS->getInit());
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 AddStmt(If->getElse());
2204 AddStmt(If->getThen());
2205 AddStmt(If->getCond());
2206 AddDecl(If->getConditionVariable());
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 // We care about the syntactic form of the initializer list, only.
2210 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2211 IE = Syntactic;
2212 EnqueueChildren(IE);
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 WL.push_back(MemberExprParts(M, Parent));
2216
2217 // If the base of the member access expression is an implicit 'this', don't
2218 // visit it.
2219 // FIXME: If we ever want to show these implicit accesses, this will be
2220 // unfortunate. However, clang_getCursor() relies on this behavior.
2221 if (!M->isImplicitAccess())
2222 AddStmt(M->getBase());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddTypeLoc(E->getEncodedTypeSourceInfo());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 EnqueueChildren(M);
2229 AddTypeLoc(M->getClassReceiverTypeInfo());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 // Visit the components of the offsetof expression.
2233 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2234 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2235 const OffsetOfNode &Node = E->getComponent(I-1);
2236 switch (Node.getKind()) {
2237 case OffsetOfNode::Array:
2238 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2239 break;
2240 case OffsetOfNode::Field:
2241 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2242 break;
2243 case OffsetOfNode::Identifier:
2244 case OffsetOfNode::Base:
2245 continue;
2246 }
2247 }
2248 // Visit the type into which we're computing the offset.
2249 AddTypeLoc(E->getTypeSourceInfo());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2253 WL.push_back(OverloadExprParts(E, Parent));
2254}
2255void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueChildren(E);
2258 if (E->isArgumentType())
2259 AddTypeLoc(E->getArgumentTypeInfo());
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 EnqueueChildren(S);
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 AddStmt(S->getBody());
2266 AddStmt(S->getCond());
2267 AddDecl(S->getConditionVariable());
2268}
2269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddStmt(W->getBody());
2272 AddStmt(W->getCond());
2273 AddDecl(W->getConditionVariable());
2274}
2275
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 for (unsigned I = E->getNumArgs(); I > 0; --I)
2278 AddTypeLoc(E->getArg(I-1));
2279}
2280
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 AddTypeLoc(E->getQueriedTypeSourceInfo());
2283}
2284
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 EnqueueChildren(E);
2287}
2288
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 VisitOverloadExpr(U);
2291 if (!U->isImplicitAccess())
2292 AddStmt(U->getBase());
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 AddStmt(E->getSubExpr());
2296 AddTypeLoc(E->getWrittenTypeInfo());
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 WL.push_back(SizeOfPackExprParts(E, Parent));
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 // If the opaque value has a source expression, just transparently
2303 // visit that. This is useful for (e.g.) pseudo-object expressions.
2304 if (Expr *SourceExpr = E->getSourceExpr())
2305 return Visit(SourceExpr);
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 AddStmt(E->getBody());
2309 WL.push_back(LambdaExprParts(E, Parent));
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 // Treat the expression like its syntactic form.
2313 Visit(E->getSyntacticForm());
2314}
2315
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002316void EnqueueVisitor::VisitOMPExecutableDirective(
2317 const OMPExecutableDirective *D) {
2318 EnqueueChildren(D);
2319 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2320 E = D->clauses().end();
2321 I != E; ++I)
2322 EnqueueChildren(*I);
2323}
2324
2325void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2326 VisitOMPExecutableDirective(D);
2327}
2328
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002329void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2330 VisitOMPExecutableDirective(D);
2331}
2332
Alexey Bataevf29276e2014-06-18 04:14:57 +00002333void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2334 VisitOMPExecutableDirective(D);
2335}
2336
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002337void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2338 VisitOMPExecutableDirective(D);
2339}
2340
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002341void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2342 VisitOMPExecutableDirective(D);
2343}
2344
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002345void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2346 VisitOMPExecutableDirective(D);
2347}
2348
Alexander Musman80c22892014-07-17 08:54:58 +00002349void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2350 VisitOMPExecutableDirective(D);
2351}
2352
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002353void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2354 VisitOMPExecutableDirective(D);
2355 AddDeclarationNameInfo(D);
2356}
2357
Alexey Bataev4acb8592014-07-07 13:01:15 +00002358void
2359EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2360 VisitOMPExecutableDirective(D);
2361}
2362
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002363void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2364 const OMPParallelSectionsDirective *D) {
2365 VisitOMPExecutableDirective(D);
2366}
2367
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002368void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2369 VisitOMPExecutableDirective(D);
2370}
2371
Alexey Bataev68446b72014-07-18 07:47:19 +00002372void
2373EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2374 VisitOMPExecutableDirective(D);
2375}
2376
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002377void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexey Bataev2df347a2014-07-18 10:17:07 +00002381void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383}
2384
Alexey Bataev6125da92014-07-21 11:26:11 +00002385void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2386 VisitOMPExecutableDirective(D);
2387}
2388
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002389void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2390 VisitOMPExecutableDirective(D);
2391}
2392
Alexey Bataev0162e452014-07-22 10:10:35 +00002393void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2394 VisitOMPExecutableDirective(D);
2395}
2396
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2399}
2400
2401bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2402 if (RegionOfInterest.isValid()) {
2403 SourceRange Range = getRawCursorExtent(C);
2404 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2405 return false;
2406 }
2407 return true;
2408}
2409
2410bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2411 while (!WL.empty()) {
2412 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002413 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002414
2415 // Set the Parent field, then back to its old value once we're done.
2416 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2417
2418 switch (LI.getKind()) {
2419 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 if (!D)
2422 continue;
2423
2424 // For now, perform default visitation for Decls.
2425 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2426 cast<DeclVisit>(&LI)->isFirst())))
2427 return true;
2428
2429 continue;
2430 }
2431 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2432 const ASTTemplateArgumentListInfo *ArgList =
2433 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2434 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2435 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2436 Arg != ArgEnd; ++Arg) {
2437 if (VisitTemplateArgumentLoc(*Arg))
2438 return true;
2439 }
2440 continue;
2441 }
2442 case VisitorJob::TypeLocVisitKind: {
2443 // Perform default visitation for TypeLocs.
2444 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2445 return true;
2446 continue;
2447 }
2448 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002449 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 if (LabelStmt *stmt = LS->getStmt()) {
2451 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2452 TU))) {
2453 return true;
2454 }
2455 }
2456 continue;
2457 }
2458
2459 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2460 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2461 if (VisitNestedNameSpecifierLoc(V->get()))
2462 return true;
2463 continue;
2464 }
2465
2466 case VisitorJob::DeclarationNameInfoVisitKind: {
2467 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2468 ->get()))
2469 return true;
2470 continue;
2471 }
2472 case VisitorJob::MemberRefVisitKind: {
2473 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2474 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2475 return true;
2476 continue;
2477 }
2478 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 if (!S)
2481 continue;
2482
2483 // Update the current cursor.
2484 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2485 if (!IsInRegionOfInterest(Cursor))
2486 continue;
2487 switch (Visitor(Cursor, Parent, ClientData)) {
2488 case CXChildVisit_Break: return true;
2489 case CXChildVisit_Continue: break;
2490 case CXChildVisit_Recurse:
2491 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002492 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 EnqueueWorkList(WL, S);
2494 break;
2495 }
2496 continue;
2497 }
2498 case VisitorJob::MemberExprPartsKind: {
2499 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002500 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002501
2502 // Visit the nested-name-specifier
2503 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2504 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2505 return true;
2506
2507 // Visit the declaration name.
2508 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2509 return true;
2510
2511 // Visit the explicitly-specified template arguments, if any.
2512 if (M->hasExplicitTemplateArgs()) {
2513 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2514 *ArgEnd = Arg + M->getNumTemplateArgs();
2515 Arg != ArgEnd; ++Arg) {
2516 if (VisitTemplateArgumentLoc(*Arg))
2517 return true;
2518 }
2519 }
2520 continue;
2521 }
2522 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 // Visit nested-name-specifier, if present.
2525 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2526 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2527 return true;
2528 // Visit declaration name.
2529 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2530 return true;
2531 continue;
2532 }
2533 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002534 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002535 // Visit the nested-name-specifier.
2536 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2537 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2538 return true;
2539 // Visit the declaration name.
2540 if (VisitDeclarationNameInfo(O->getNameInfo()))
2541 return true;
2542 // Visit the overloaded declaration reference.
2543 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2544 return true;
2545 continue;
2546 }
2547 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002548 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 NamedDecl *Pack = E->getPack();
2550 if (isa<TemplateTypeParmDecl>(Pack)) {
2551 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2552 E->getPackLoc(), TU)))
2553 return true;
2554
2555 continue;
2556 }
2557
2558 if (isa<TemplateTemplateParmDecl>(Pack)) {
2559 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2560 E->getPackLoc(), TU)))
2561 return true;
2562
2563 continue;
2564 }
2565
2566 // Non-type template parameter packs and function parameter packs are
2567 // treated like DeclRefExpr cursors.
2568 continue;
2569 }
2570
2571 case VisitorJob::LambdaExprPartsKind: {
2572 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002573 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002574 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2575 CEnd = E->explicit_capture_end();
2576 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002577 // FIXME: Lambda init-captures.
2578 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002579 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002580
Guy Benyei11169dd2012-12-18 14:30:41 +00002581 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2582 C->getLocation(),
2583 TU)))
2584 return true;
2585 }
2586
2587 // Visit parameters and return type, if present.
2588 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2589 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2590 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2591 // Visit the whole type.
2592 if (Visit(TL))
2593 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002594 } else if (FunctionProtoTypeLoc Proto =
2595 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 if (E->hasExplicitParameters()) {
2597 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002598 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2599 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002600 return true;
2601 } else {
2602 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002603 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002604 return true;
2605 }
2606 }
2607 }
2608 break;
2609 }
2610
2611 case VisitorJob::PostChildrenVisitKind:
2612 if (PostChildrenVisitor(Parent, ClientData))
2613 return true;
2614 break;
2615 }
2616 }
2617 return false;
2618}
2619
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002620bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002621 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 if (!WorkListFreeList.empty()) {
2623 WL = WorkListFreeList.back();
2624 WL->clear();
2625 WorkListFreeList.pop_back();
2626 }
2627 else {
2628 WL = new VisitorWorkList();
2629 WorkListCache.push_back(WL);
2630 }
2631 EnqueueWorkList(*WL, S);
2632 bool result = RunVisitorWorkList(*WL);
2633 WorkListFreeList.push_back(WL);
2634 return result;
2635}
2636
2637namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002638typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002639RefNamePieces
2640buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2641 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2642 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002643 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2644 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2645 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2646
2647 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2648
2649 RefNamePieces Pieces;
2650
2651 if (WantQualifier && QLoc.isValid())
2652 Pieces.push_back(QLoc);
2653
2654 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2655 Pieces.push_back(NI.getLoc());
2656
2657 if (WantTemplateArgs && TemplateArgs)
2658 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2659 TemplateArgs->RAngleLoc));
2660
2661 if (Kind == DeclarationName::CXXOperatorName) {
2662 Pieces.push_back(SourceLocation::getFromRawEncoding(
2663 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2664 Pieces.push_back(SourceLocation::getFromRawEncoding(
2665 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2666 }
2667
2668 if (WantSinglePiece) {
2669 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2670 Pieces.clear();
2671 Pieces.push_back(R);
2672 }
2673
2674 return Pieces;
2675}
2676}
2677
2678//===----------------------------------------------------------------------===//
2679// Misc. API hooks.
2680//===----------------------------------------------------------------------===//
2681
Chad Rosier05c71aa2013-03-27 18:28:23 +00002682static void fatal_error_handler(void *user_data, const std::string& reason,
2683 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 // Write the result out to stderr avoiding errs() because raw_ostreams can
2685 // call report_fatal_error.
2686 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2687 ::abort();
2688}
2689
Chandler Carruth66660742014-06-27 16:37:27 +00002690namespace {
2691struct RegisterFatalErrorHandler {
2692 RegisterFatalErrorHandler() {
2693 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2694 }
2695};
2696}
2697
2698static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2699
Guy Benyei11169dd2012-12-18 14:30:41 +00002700extern "C" {
2701CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2702 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 // We use crash recovery to make some of our APIs more reliable, implicitly
2704 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002705 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2706 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002707
Chandler Carruth66660742014-06-27 16:37:27 +00002708 // Look through the managed static to trigger construction of the managed
2709 // static which registers our fatal error handler. This ensures it is only
2710 // registered once.
2711 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002712
2713 CIndexer *CIdxr = new CIndexer();
2714 if (excludeDeclarationsFromPCH)
2715 CIdxr->setOnlyLocalDecls();
2716 if (displayDiagnostics)
2717 CIdxr->setDisplayDiagnostics();
2718
2719 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2720 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2721 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2722 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2723 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2724 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2725
2726 return CIdxr;
2727}
2728
2729void clang_disposeIndex(CXIndex CIdx) {
2730 if (CIdx)
2731 delete static_cast<CIndexer *>(CIdx);
2732}
2733
2734void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2735 if (CIdx)
2736 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2737}
2738
2739unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2740 if (CIdx)
2741 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2742 return 0;
2743}
2744
2745void clang_toggleCrashRecovery(unsigned isEnabled) {
2746 if (isEnabled)
2747 llvm::CrashRecoveryContext::Enable();
2748 else
2749 llvm::CrashRecoveryContext::Disable();
2750}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002751
Guy Benyei11169dd2012-12-18 14:30:41 +00002752CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2753 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002754 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002755 enum CXErrorCode Result =
2756 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002757 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 assert((TU && Result == CXError_Success) ||
2759 (!TU && Result != CXError_Success));
2760 return TU;
2761}
2762
2763enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2764 const char *ast_filename,
2765 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002766 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002767 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002768
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002769 if (!CIdx || !ast_filename || !out_TU)
2770 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002771
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002772 LOG_FUNC_SECTION {
2773 *Log << ast_filename;
2774 }
2775
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2777 FileSystemOptions FileSystemOpts;
2778
2779 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002780 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002781 CXXIdx->getOnlyLocalDecls(), None,
2782 /*CaptureDiagnostics=*/true,
2783 /*AllowPCHWithCompilerErrors=*/true,
2784 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002785 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2786 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002787}
2788
2789unsigned clang_defaultEditingTranslationUnitOptions() {
2790 return CXTranslationUnit_PrecompiledPreamble |
2791 CXTranslationUnit_CacheCompletionResults;
2792}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794CXTranslationUnit
2795clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2796 const char *source_filename,
2797 int num_command_line_args,
2798 const char * const *command_line_args,
2799 unsigned num_unsaved_files,
2800 struct CXUnsavedFile *unsaved_files) {
2801 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2802 return clang_parseTranslationUnit(CIdx, source_filename,
2803 command_line_args, num_command_line_args,
2804 unsaved_files, num_unsaved_files,
2805 Options);
2806}
2807
2808struct ParseTranslationUnitInfo {
2809 CXIndex CIdx;
2810 const char *source_filename;
2811 const char *const *command_line_args;
2812 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002813 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002816 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002817};
2818static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002819 const ParseTranslationUnitInfo *PTUI =
2820 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002821 CXIndex CIdx = PTUI->CIdx;
2822 const char *source_filename = PTUI->source_filename;
2823 const char * const *command_line_args = PTUI->command_line_args;
2824 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002825 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002826 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002827
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002828 // Set up the initial return values.
2829 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002830 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002831
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002832 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002833 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002834 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002836 }
2837
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2839
2840 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2841 setThreadBackgroundPriority();
2842
2843 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2844 // FIXME: Add a flag for modules.
2845 TranslationUnitKind TUKind
2846 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002847 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 = options & CXTranslationUnit_CacheCompletionResults;
2849 bool IncludeBriefCommentsInCodeCompletion
2850 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2851 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2852 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2853
2854 // Configure the diagnostics.
2855 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002856 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002857
2858 // Recover resources if we crash before exiting this function.
2859 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2860 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002861 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002862
Ahmed Charlesb8984322014-03-07 20:03:18 +00002863 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2864 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002865
2866 // Recover resources if we crash before exiting this function.
2867 llvm::CrashRecoveryContextCleanupRegistrar<
2868 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2869
Alp Toker9d85b182014-07-07 01:23:14 +00002870 for (auto &UF : PTUI->unsaved_files) {
2871 llvm::MemoryBuffer *MB =
2872 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2873 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002874 }
2875
Ahmed Charlesb8984322014-03-07 20:03:18 +00002876 std::unique_ptr<std::vector<const char *>> Args(
2877 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002878
2879 // Recover resources if we crash before exiting this method.
2880 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2881 ArgsCleanup(Args.get());
2882
2883 // Since the Clang C library is primarily used by batch tools dealing with
2884 // (often very broken) source code, where spell-checking can have a
2885 // significant negative impact on performance (particularly when
2886 // precompiled headers are involved), we disable it by default.
2887 // Only do this if we haven't found a spell-checking-related argument.
2888 bool FoundSpellCheckingArgument = false;
2889 for (int I = 0; I != num_command_line_args; ++I) {
2890 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2891 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2892 FoundSpellCheckingArgument = true;
2893 break;
2894 }
2895 }
2896 if (!FoundSpellCheckingArgument)
2897 Args->push_back("-fno-spell-checking");
2898
2899 Args->insert(Args->end(), command_line_args,
2900 command_line_args + num_command_line_args);
2901
2902 // The 'source_filename' argument is optional. If the caller does not
2903 // specify it then it is assumed that the source file is specified
2904 // in the actual argument list.
2905 // Put the source file after command_line_args otherwise if '-x' flag is
2906 // present it will be unused.
2907 if (source_filename)
2908 Args->push_back(source_filename);
2909
2910 // Do we need the detailed preprocessing record?
2911 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2912 Args->push_back("-Xclang");
2913 Args->push_back("-detailed-preprocessing-record");
2914 }
2915
2916 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002917 std::unique_ptr<ASTUnit> ErrUnit;
2918 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002919 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002920 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2921 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2922 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2923 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2924 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2925 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002926
2927 if (NumErrors != Diags->getClient()->getNumErrors()) {
2928 // Make sure to check that 'Unit' is non-NULL.
2929 if (CXXIdx->getDisplayDiagnostics())
2930 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2931 }
2932
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002933 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2934 PTUI->result = CXError_ASTReadError;
2935 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002936 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002937 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2938 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002939}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002940
2941CXTranslationUnit
2942clang_parseTranslationUnit(CXIndex CIdx,
2943 const char *source_filename,
2944 const char *const *command_line_args,
2945 int num_command_line_args,
2946 struct CXUnsavedFile *unsaved_files,
2947 unsigned num_unsaved_files,
2948 unsigned options) {
2949 CXTranslationUnit TU;
2950 enum CXErrorCode Result = clang_parseTranslationUnit2(
2951 CIdx, source_filename, command_line_args, num_command_line_args,
2952 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002953 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002954 assert((TU && Result == CXError_Success) ||
2955 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002956 return TU;
2957}
2958
2959enum CXErrorCode clang_parseTranslationUnit2(
2960 CXIndex CIdx,
2961 const char *source_filename,
2962 const char *const *command_line_args,
2963 int num_command_line_args,
2964 struct CXUnsavedFile *unsaved_files,
2965 unsigned num_unsaved_files,
2966 unsigned options,
2967 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002968 LOG_FUNC_SECTION {
2969 *Log << source_filename << ": ";
2970 for (int i = 0; i != num_command_line_args; ++i)
2971 *Log << command_line_args[i] << " ";
2972 }
2973
Alp Toker9d85b182014-07-07 01:23:14 +00002974 if (num_unsaved_files && !unsaved_files)
2975 return CXError_InvalidArguments;
2976
Alp Toker5c532982014-07-07 22:42:03 +00002977 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002978 ParseTranslationUnitInfo PTUI = {
2979 CIdx,
2980 source_filename,
2981 command_line_args,
2982 num_command_line_args,
2983 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2984 options,
2985 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002986 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002987 llvm::CrashRecoveryContext CRC;
2988
2989 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2990 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2991 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2992 fprintf(stderr, " 'command_line_args' : [");
2993 for (int i = 0; i != num_command_line_args; ++i) {
2994 if (i)
2995 fprintf(stderr, ", ");
2996 fprintf(stderr, "'%s'", command_line_args[i]);
2997 }
2998 fprintf(stderr, "],\n");
2999 fprintf(stderr, " 'unsaved_files' : [");
3000 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3001 if (i)
3002 fprintf(stderr, ", ");
3003 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3004 unsaved_files[i].Length);
3005 }
3006 fprintf(stderr, "],\n");
3007 fprintf(stderr, " 'options' : %d,\n", options);
3008 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009
3010 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012 if (CXTranslationUnit *TU = PTUI.out_TU)
3013 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 }
Alp Toker5c532982014-07-07 22:42:03 +00003015
3016 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003017}
3018
3019unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3020 return CXSaveTranslationUnit_None;
3021}
3022
3023namespace {
3024
3025struct SaveTranslationUnitInfo {
3026 CXTranslationUnit TU;
3027 const char *FileName;
3028 unsigned options;
3029 CXSaveError result;
3030};
3031
3032}
3033
3034static void clang_saveTranslationUnit_Impl(void *UserData) {
3035 SaveTranslationUnitInfo *STUI =
3036 static_cast<SaveTranslationUnitInfo*>(UserData);
3037
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003038 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3040 setThreadBackgroundPriority();
3041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003042 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3044}
3045
3046int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3047 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003048 LOG_FUNC_SECTION {
3049 *Log << TU << ' ' << FileName;
3050 }
3051
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003052 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003053 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003055 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003057 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3059 if (!CXXUnit->hasSema())
3060 return CXSaveError_InvalidTU;
3061
3062 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3063
3064 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3065 getenv("LIBCLANG_NOTHREADS")) {
3066 clang_saveTranslationUnit_Impl(&STUI);
3067
3068 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3069 PrintLibclangResourceUsage(TU);
3070
3071 return STUI.result;
3072 }
3073
3074 // We have an AST that has invalid nodes due to compiler errors.
3075 // Use a crash recovery thread for protection.
3076
3077 llvm::CrashRecoveryContext CRC;
3078
3079 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3080 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3081 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3082 fprintf(stderr, " 'options' : %d,\n", options);
3083 fprintf(stderr, "}\n");
3084
3085 return CXSaveError_Unknown;
3086
3087 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3088 PrintLibclangResourceUsage(TU);
3089 }
3090
3091 return STUI.result;
3092}
3093
3094void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3095 if (CTUnit) {
3096 // If the translation unit has been marked as unsafe to free, just discard
3097 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003098 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3099 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 return;
3101
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003102 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003103 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3105 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003106 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 delete CTUnit;
3108 }
3109}
3110
3111unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3112 return CXReparse_None;
3113}
3114
3115struct ReparseTranslationUnitInfo {
3116 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003117 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003119 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120};
3121
3122static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003123 const ReparseTranslationUnitInfo *RTUI =
3124 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003126 unsigned options = RTUI->options;
3127 (void) options;
3128
3129 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003130 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003132 RTUI->result = CXError_InvalidArguments;
3133 return;
3134 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003135
3136 // Reset the associated diagnostics.
3137 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003138 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003139
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003140 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3142 setThreadBackgroundPriority();
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003145 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003146
3147 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3148 new std::vector<ASTUnit::RemappedFile>());
3149
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 // Recover resources if we crash before exiting this function.
3151 llvm::CrashRecoveryContextCleanupRegistrar<
3152 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003153
3154 for (auto &UF : RTUI->unsaved_files) {
3155 llvm::MemoryBuffer *MB =
3156 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3157 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003159
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003160 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003161 RTUI->result = CXError_Success;
3162 else if (isASTReadError(CXXUnit))
3163 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003164}
3165
3166int clang_reparseTranslationUnit(CXTranslationUnit TU,
3167 unsigned num_unsaved_files,
3168 struct CXUnsavedFile *unsaved_files,
3169 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003170 LOG_FUNC_SECTION {
3171 *Log << TU;
3172 }
3173
Alp Toker9d85b182014-07-07 01:23:14 +00003174 if (num_unsaved_files && !unsaved_files)
3175 return CXError_InvalidArguments;
3176
Alp Toker5c532982014-07-07 22:42:03 +00003177 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003178 ReparseTranslationUnitInfo RTUI = {
3179 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003180 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003181
3182 if (getenv("LIBCLANG_NOTHREADS")) {
3183 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003184 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 }
3186
3187 llvm::CrashRecoveryContext CRC;
3188
3189 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3190 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003191 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003192 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3194 PrintLibclangResourceUsage(TU);
3195
Alp Toker5c532982014-07-07 22:42:03 +00003196 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003197}
3198
3199
3200CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003201 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003202 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003203 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003204 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003205
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003206 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003207 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003208}
3209
3210CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003211 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003212 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003213 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003214 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003215
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003216 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3218}
3219
3220} // end: extern "C"
3221
3222//===----------------------------------------------------------------------===//
3223// CXFile Operations.
3224//===----------------------------------------------------------------------===//
3225
3226extern "C" {
3227CXString clang_getFileName(CXFile SFile) {
3228 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003229 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003230
3231 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003232 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003233}
3234
3235time_t clang_getFileTime(CXFile SFile) {
3236 if (!SFile)
3237 return 0;
3238
3239 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3240 return FEnt->getModificationTime();
3241}
3242
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003243CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003244 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003245 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003246 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003247 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003249 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003250
3251 FileManager &FMgr = CXXUnit->getFileManager();
3252 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3253}
3254
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003255unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3256 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003257 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003258 LOG_BAD_TU(TU);
3259 return 0;
3260 }
3261
3262 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 return 0;
3264
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003265 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 FileEntry *FEnt = static_cast<FileEntry *>(file);
3267 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3268 .isFileMultipleIncludeGuarded(FEnt);
3269}
3270
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003271int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3272 if (!file || !outID)
3273 return 1;
3274
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003275 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003276 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3277 outID->data[0] = ID.getDevice();
3278 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003279 outID->data[2] = FEnt->getModificationTime();
3280 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003281}
3282
Guy Benyei11169dd2012-12-18 14:30:41 +00003283} // end: extern "C"
3284
3285//===----------------------------------------------------------------------===//
3286// CXCursor Operations.
3287//===----------------------------------------------------------------------===//
3288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289static const Decl *getDeclFromExpr(const Stmt *E) {
3290 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 return getDeclFromExpr(CE->getSubExpr());
3292
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003293 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003299 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 if (PRE->isExplicitProperty())
3301 return PRE->getExplicitProperty();
3302 // It could be messaging both getter and setter as in:
3303 // ++myobj.myprop;
3304 // in which case prefer to associate the setter since it is less obvious
3305 // from inspecting the source that the setter is going to get called.
3306 if (PRE->isMessagingSetter())
3307 return PRE->getImplicitPropertySetter();
3308 return PRE->getImplicitPropertyGetter();
3309 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 if (Expr *Src = OVE->getSourceExpr())
3314 return getDeclFromExpr(Src);
3315
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003316 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (!CE->isElidable())
3320 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003321 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 return OME->getMethodDecl();
3323
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003324 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003326 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3328 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3331 isa<ParmVarDecl>(SizeOfPack->getPack()))
3332 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003333
3334 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335}
3336
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003337static SourceLocation getLocationFromExpr(const Expr *E) {
3338 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return getLocationFromExpr(CE->getSubExpr());
3340
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003341 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003343 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003345 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003347 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003349 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003351 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 return PropRef->getLocation();
3353
3354 return E->getLocStart();
3355}
3356
3357extern "C" {
3358
3359unsigned clang_visitChildren(CXCursor parent,
3360 CXCursorVisitor visitor,
3361 CXClientData client_data) {
3362 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3363 /*VisitPreprocessorLast=*/false);
3364 return CursorVis.VisitChildren(parent);
3365}
3366
3367#ifndef __has_feature
3368#define __has_feature(x) 0
3369#endif
3370#if __has_feature(blocks)
3371typedef enum CXChildVisitResult
3372 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3373
3374static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3375 CXClientData client_data) {
3376 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3377 return block(cursor, parent);
3378}
3379#else
3380// If we are compiled with a compiler that doesn't have native blocks support,
3381// define and call the block manually, so the
3382typedef struct _CXChildVisitResult
3383{
3384 void *isa;
3385 int flags;
3386 int reserved;
3387 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3388 CXCursor);
3389} *CXCursorVisitorBlock;
3390
3391static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3392 CXClientData client_data) {
3393 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3394 return block->invoke(block, cursor, parent);
3395}
3396#endif
3397
3398
3399unsigned clang_visitChildrenWithBlock(CXCursor parent,
3400 CXCursorVisitorBlock block) {
3401 return clang_visitChildren(parent, visitWithBlock, block);
3402}
3403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003406 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003408 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const ObjCPropertyImplDecl *PropImpl =
3411 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003413 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003417 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003419 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 }
3421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003422 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003423 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3427 // and returns different names. NamedDecl returns the class name and
3428 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003429 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430
3431 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003432 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 SmallString<1024> S;
3435 llvm::raw_svector_ostream os(S);
3436 ND->printName(os);
3437
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003438 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439}
3440
3441CXString clang_getCursorSpelling(CXCursor C) {
3442 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003443 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003444
3445 if (clang_isReference(C.kind)) {
3446 switch (C.kind) {
3447 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003448 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003449 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
3451 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003452 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003453 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003456 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003458 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 }
3460 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003461 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003462 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 }
3464 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003465 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 assert(Type && "Missing type decl");
3467
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003468 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 getAsString());
3470 }
3471 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003472 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 assert(Template && "Missing template decl");
3474
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003475 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 }
3477
3478 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003479 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 assert(NS && "Missing namespace decl");
3481
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003482 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 }
3484
3485 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003486 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 assert(Field && "Missing member decl");
3488
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003489 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 }
3491
3492 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003493 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 assert(Label && "Missing label");
3495
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003496 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 }
3498
3499 case CXCursor_OverloadedDeclRef: {
3500 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3502 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003503 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003504 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003507 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 OverloadedTemplateStorage *Ovl
3509 = Storage.get<OverloadedTemplateStorage*>();
3510 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003511 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003512 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514
3515 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003516 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 assert(Var && "Missing variable decl");
3518
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003519 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 }
3521
3522 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003523 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 }
3525 }
3526
3527 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003528 const Expr *E = getCursorExpr(C);
3529
3530 if (C.kind == CXCursor_ObjCStringLiteral ||
3531 C.kind == CXCursor_StringLiteral) {
3532 const StringLiteral *SLit;
3533 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3534 SLit = OSL->getString();
3535 } else {
3536 SLit = cast<StringLiteral>(E);
3537 }
3538 SmallString<256> Buf;
3539 llvm::raw_svector_ostream OS(Buf);
3540 SLit->outputString(OS);
3541 return cxstring::createDup(OS.str());
3542 }
3543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 if (D)
3546 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003547 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 }
3549
3550 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003551 const Stmt *S = getCursorStmt(C);
3552 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003554
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003555 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 }
3557
3558 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 ->getNameStart());
3561
3562 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 ->getNameStart());
3565
3566 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568
3569 if (clang_isDeclaration(C.kind))
3570 return getDeclSpelling(getCursorDecl(C));
3571
3572 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003573 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003574 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 }
3576
3577 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003578 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 }
3581
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003582 if (C.kind == CXCursor_PackedAttr) {
3583 return cxstring::createRef("packed");
3584 }
3585
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003586 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003587}
3588
3589CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3590 unsigned pieceIndex,
3591 unsigned options) {
3592 if (clang_Cursor_isNull(C))
3593 return clang_getNullRange();
3594
3595 ASTContext &Ctx = getCursorContext(C);
3596
3597 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003598 const Stmt *S = getCursorStmt(C);
3599 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 if (pieceIndex > 0)
3601 return clang_getNullRange();
3602 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3603 }
3604
3605 return clang_getNullRange();
3606 }
3607
3608 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003609 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3611 if (pieceIndex >= ME->getNumSelectorLocs())
3612 return clang_getNullRange();
3613 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3614 }
3615 }
3616
3617 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3618 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003619 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3621 if (pieceIndex >= MD->getNumSelectorLocs())
3622 return clang_getNullRange();
3623 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3624 }
3625 }
3626
3627 if (C.kind == CXCursor_ObjCCategoryDecl ||
3628 C.kind == CXCursor_ObjCCategoryImplDecl) {
3629 if (pieceIndex > 0)
3630 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003631 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3633 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003634 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3636 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3637 }
3638
3639 if (C.kind == CXCursor_ModuleImportDecl) {
3640 if (pieceIndex > 0)
3641 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003642 if (const ImportDecl *ImportD =
3643 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3645 if (!Locs.empty())
3646 return cxloc::translateSourceRange(Ctx,
3647 SourceRange(Locs.front(), Locs.back()));
3648 }
3649 return clang_getNullRange();
3650 }
3651
3652 // FIXME: A CXCursor_InclusionDirective should give the location of the
3653 // filename, but we don't keep track of this.
3654
3655 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3656 // but we don't keep track of this.
3657
3658 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3659 // but we don't keep track of this.
3660
3661 // Default handling, give the location of the cursor.
3662
3663 if (pieceIndex > 0)
3664 return clang_getNullRange();
3665
3666 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3667 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3668 return cxloc::translateSourceRange(Ctx, Loc);
3669}
3670
Eli Bendersky44a206f2014-07-31 18:04:56 +00003671CXString clang_Cursor_getMangling(CXCursor C) {
3672 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3673 return cxstring::createEmpty();
3674
3675 const Decl *D = getCursorDecl(C);
3676 // Mangling only works for functions and variables.
3677 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3678 return cxstring::createEmpty();
3679
3680 const NamedDecl *ND = cast<NamedDecl>(D);
3681 std::unique_ptr<MangleContext> MC(ND->getASTContext().createMangleContext());
3682
3683 std::string Buf;
3684 llvm::raw_string_ostream OS(Buf);
3685 MC->mangleName(ND, OS);
3686 OS.flush();
3687
3688 // The Microsoft mangler may insert a special character in the beginning to
3689 // prevent further mangling. We can strip that for display purposes.
3690 if (Buf[0] == '\x01') {
3691 Buf.erase(0, 1);
3692 }
3693 return cxstring::createDup(Buf);
3694}
3695
Guy Benyei11169dd2012-12-18 14:30:41 +00003696CXString clang_getCursorDisplayName(CXCursor C) {
3697 if (!clang_isDeclaration(C.kind))
3698 return clang_getCursorSpelling(C);
3699
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003700 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003702 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003703
3704 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003705 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 D = FunTmpl->getTemplatedDecl();
3707
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003708 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 SmallString<64> Str;
3710 llvm::raw_svector_ostream OS(Str);
3711 OS << *Function;
3712 if (Function->getPrimaryTemplate())
3713 OS << "<>";
3714 OS << "(";
3715 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3716 if (I)
3717 OS << ", ";
3718 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3719 }
3720
3721 if (Function->isVariadic()) {
3722 if (Function->getNumParams())
3723 OS << ", ";
3724 OS << "...";
3725 }
3726 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003727 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 }
3729
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003730 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 SmallString<64> Str;
3732 llvm::raw_svector_ostream OS(Str);
3733 OS << *ClassTemplate;
3734 OS << "<";
3735 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3736 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3737 if (I)
3738 OS << ", ";
3739
3740 NamedDecl *Param = Params->getParam(I);
3741 if (Param->getIdentifier()) {
3742 OS << Param->getIdentifier()->getName();
3743 continue;
3744 }
3745
3746 // There is no parameter name, which makes this tricky. Try to come up
3747 // with something useful that isn't too long.
3748 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3749 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3750 else if (NonTypeTemplateParmDecl *NTTP
3751 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3752 OS << NTTP->getType().getAsString(Policy);
3753 else
3754 OS << "template<...> class";
3755 }
3756
3757 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003758 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 }
3760
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003761 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3763 // If the type was explicitly written, use that.
3764 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003765 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003766
Benjamin Kramer9170e912013-02-22 15:46:01 +00003767 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 llvm::raw_svector_ostream OS(Str);
3769 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003770 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 ClassSpec->getTemplateArgs().data(),
3772 ClassSpec->getTemplateArgs().size(),
3773 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003774 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 }
3776
3777 return clang_getCursorSpelling(C);
3778}
3779
3780CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3781 switch (Kind) {
3782 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003910 case CXCursor_ObjCSelfExpr:
3911 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004000 case CXCursor_SEHLeaveStmt:
4001 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004030 case CXCursor_PackedAttr:
4031 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004032 case CXCursor_PureAttr:
4033 return cxstring::createRef("attribute(pure)");
4034 case CXCursor_ConstAttr:
4035 return cxstring::createRef("attribute(const)");
4036 case CXCursor_NoDuplicateAttr:
4037 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004038 case CXCursor_CUDAConstantAttr:
4039 return cxstring::createRef("attribute(constant)");
4040 case CXCursor_CUDADeviceAttr:
4041 return cxstring::createRef("attribute(device)");
4042 case CXCursor_CUDAGlobalAttr:
4043 return cxstring::createRef("attribute(global)");
4044 case CXCursor_CUDAHostAttr:
4045 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004094 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004095 return cxstring::createRef("OMPParallelDirective");
4096 case CXCursor_OMPSimdDirective:
4097 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004098 case CXCursor_OMPForDirective:
4099 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004100 case CXCursor_OMPSectionsDirective:
4101 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004102 case CXCursor_OMPSectionDirective:
4103 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004104 case CXCursor_OMPSingleDirective:
4105 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004106 case CXCursor_OMPMasterDirective:
4107 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004108 case CXCursor_OMPCriticalDirective:
4109 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004110 case CXCursor_OMPParallelForDirective:
4111 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004112 case CXCursor_OMPParallelSectionsDirective:
4113 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004114 case CXCursor_OMPTaskDirective:
4115 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004116 case CXCursor_OMPTaskyieldDirective:
4117 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004118 case CXCursor_OMPBarrierDirective:
4119 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004120 case CXCursor_OMPTaskwaitDirective:
4121 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004122 case CXCursor_OMPFlushDirective:
4123 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004124 case CXCursor_OMPOrderedDirective:
4125 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004126 case CXCursor_OMPAtomicDirective:
4127 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 }
4129
4130 llvm_unreachable("Unhandled CXCursorKind");
4131}
4132
4133struct GetCursorData {
4134 SourceLocation TokenBeginLoc;
4135 bool PointsAtMacroArgExpansion;
4136 bool VisitedObjCPropertyImplDecl;
4137 SourceLocation VisitedDeclaratorDeclStartLoc;
4138 CXCursor &BestCursor;
4139
4140 GetCursorData(SourceManager &SM,
4141 SourceLocation tokenBegin, CXCursor &outputCursor)
4142 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4143 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4144 VisitedObjCPropertyImplDecl = false;
4145 }
4146};
4147
4148static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4149 CXCursor parent,
4150 CXClientData client_data) {
4151 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4152 CXCursor *BestCursor = &Data->BestCursor;
4153
4154 // If we point inside a macro argument we should provide info of what the
4155 // token is so use the actual cursor, don't replace it with a macro expansion
4156 // cursor.
4157 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4158 return CXChildVisit_Recurse;
4159
4160 if (clang_isDeclaration(cursor.kind)) {
4161 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004162 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4164 if (MD->isImplicit())
4165 return CXChildVisit_Break;
4166
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004167 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4169 // Check that when we have multiple @class references in the same line,
4170 // that later ones do not override the previous ones.
4171 // If we have:
4172 // @class Foo, Bar;
4173 // source ranges for both start at '@', so 'Bar' will end up overriding
4174 // 'Foo' even though the cursor location was at 'Foo'.
4175 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4176 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004177 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4179 if (PrevID != ID &&
4180 !PrevID->isThisDeclarationADefinition() &&
4181 !ID->isThisDeclarationADefinition())
4182 return CXChildVisit_Break;
4183 }
4184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004185 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4187 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4188 // Check that when we have multiple declarators in the same line,
4189 // that later ones do not override the previous ones.
4190 // If we have:
4191 // int Foo, Bar;
4192 // source ranges for both start at 'int', so 'Bar' will end up overriding
4193 // 'Foo' even though the cursor location was at 'Foo'.
4194 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4195 return CXChildVisit_Break;
4196 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4197
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004198 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4200 (void)PropImp;
4201 // Check that when we have multiple @synthesize in the same line,
4202 // that later ones do not override the previous ones.
4203 // If we have:
4204 // @synthesize Foo, Bar;
4205 // source ranges for both start at '@', so 'Bar' will end up overriding
4206 // 'Foo' even though the cursor location was at 'Foo'.
4207 if (Data->VisitedObjCPropertyImplDecl)
4208 return CXChildVisit_Break;
4209 Data->VisitedObjCPropertyImplDecl = true;
4210 }
4211 }
4212
4213 if (clang_isExpression(cursor.kind) &&
4214 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004215 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 // Avoid having the cursor of an expression replace the declaration cursor
4217 // when the expression source range overlaps the declaration range.
4218 // This can happen for C++ constructor expressions whose range generally
4219 // include the variable declaration, e.g.:
4220 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4221 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4222 D->getLocation() == Data->TokenBeginLoc)
4223 return CXChildVisit_Break;
4224 }
4225 }
4226
4227 // If our current best cursor is the construction of a temporary object,
4228 // don't replace that cursor with a type reference, because we want
4229 // clang_getCursor() to point at the constructor.
4230 if (clang_isExpression(BestCursor->kind) &&
4231 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4232 cursor.kind == CXCursor_TypeRef) {
4233 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4234 // as having the actual point on the type reference.
4235 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4236 return CXChildVisit_Recurse;
4237 }
4238
4239 *BestCursor = cursor;
4240 return CXChildVisit_Recurse;
4241}
4242
4243CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004244 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004245 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004247 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004249 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4251
4252 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4253 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4254
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004255 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 CXFile SearchFile;
4257 unsigned SearchLine, SearchColumn;
4258 CXFile ResultFile;
4259 unsigned ResultLine, ResultColumn;
4260 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4261 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4262 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004263
4264 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4265 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004266 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004267 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 SearchFileName = clang_getFileName(SearchFile);
4269 ResultFileName = clang_getFileName(ResultFile);
4270 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4271 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004272 *Log << llvm::format("(%s:%d:%d) = %s",
4273 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4274 clang_getCString(KindSpelling))
4275 << llvm::format("(%s:%d:%d):%s%s",
4276 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4277 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 clang_disposeString(SearchFileName);
4279 clang_disposeString(ResultFileName);
4280 clang_disposeString(KindSpelling);
4281 clang_disposeString(USR);
4282
4283 CXCursor Definition = clang_getCursorDefinition(Result);
4284 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4285 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4286 CXString DefinitionKindSpelling
4287 = clang_getCursorKindSpelling(Definition.kind);
4288 CXFile DefinitionFile;
4289 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004290 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004291 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004293 *Log << llvm::format(" -> %s(%s:%d:%d)",
4294 clang_getCString(DefinitionKindSpelling),
4295 clang_getCString(DefinitionFileName),
4296 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 clang_disposeString(DefinitionFileName);
4298 clang_disposeString(DefinitionKindSpelling);
4299 }
4300 }
4301
4302 return Result;
4303}
4304
4305CXCursor clang_getNullCursor(void) {
4306 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4307}
4308
4309unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004310 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4311 // can't set consistently. For example, when visiting a DeclStmt we will set
4312 // it but we don't set it on the result of clang_getCursorDefinition for
4313 // a reference of the same declaration.
4314 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4315 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4316 // to provide that kind of info.
4317 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004318 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004319 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004320 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004321
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 return X == Y;
4323}
4324
4325unsigned clang_hashCursor(CXCursor C) {
4326 unsigned Index = 0;
4327 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4328 Index = 1;
4329
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004330 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 std::make_pair(C.kind, C.data[Index]));
4332}
4333
4334unsigned clang_isInvalid(enum CXCursorKind K) {
4335 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4336}
4337
4338unsigned clang_isDeclaration(enum CXCursorKind K) {
4339 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4340 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4341}
4342
4343unsigned clang_isReference(enum CXCursorKind K) {
4344 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4345}
4346
4347unsigned clang_isExpression(enum CXCursorKind K) {
4348 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4349}
4350
4351unsigned clang_isStatement(enum CXCursorKind K) {
4352 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4353}
4354
4355unsigned clang_isAttribute(enum CXCursorKind K) {
4356 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4357}
4358
4359unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4360 return K == CXCursor_TranslationUnit;
4361}
4362
4363unsigned clang_isPreprocessing(enum CXCursorKind K) {
4364 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4365}
4366
4367unsigned clang_isUnexposed(enum CXCursorKind K) {
4368 switch (K) {
4369 case CXCursor_UnexposedDecl:
4370 case CXCursor_UnexposedExpr:
4371 case CXCursor_UnexposedStmt:
4372 case CXCursor_UnexposedAttr:
4373 return true;
4374 default:
4375 return false;
4376 }
4377}
4378
4379CXCursorKind clang_getCursorKind(CXCursor C) {
4380 return C.kind;
4381}
4382
4383CXSourceLocation clang_getCursorLocation(CXCursor C) {
4384 if (clang_isReference(C.kind)) {
4385 switch (C.kind) {
4386 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004387 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 = getCursorObjCSuperClassRef(C);
4389 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4390 }
4391
4392 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004393 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 = getCursorObjCProtocolRef(C);
4395 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4396 }
4397
4398 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004399 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 = getCursorObjCClassRef(C);
4401 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4402 }
4403
4404 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004405 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4407 }
4408
4409 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004410 std::pair<const TemplateDecl *, SourceLocation> P =
4411 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4413 }
4414
4415 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004416 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4418 }
4419
4420 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004421 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4423 }
4424
4425 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004426 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4428 }
4429
4430 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004431 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!BaseSpec)
4433 return clang_getNullLocation();
4434
4435 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4436 return cxloc::translateSourceLocation(getCursorContext(C),
4437 TSInfo->getTypeLoc().getBeginLoc());
4438
4439 return cxloc::translateSourceLocation(getCursorContext(C),
4440 BaseSpec->getLocStart());
4441 }
4442
4443 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004444 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4446 }
4447
4448 case CXCursor_OverloadedDeclRef:
4449 return cxloc::translateSourceLocation(getCursorContext(C),
4450 getCursorOverloadedDeclRef(C).second);
4451
4452 default:
4453 // FIXME: Need a way to enumerate all non-reference cases.
4454 llvm_unreachable("Missed a reference kind");
4455 }
4456 }
4457
4458 if (clang_isExpression(C.kind))
4459 return cxloc::translateSourceLocation(getCursorContext(C),
4460 getLocationFromExpr(getCursorExpr(C)));
4461
4462 if (clang_isStatement(C.kind))
4463 return cxloc::translateSourceLocation(getCursorContext(C),
4464 getCursorStmt(C)->getLocStart());
4465
4466 if (C.kind == CXCursor_PreprocessingDirective) {
4467 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4468 return cxloc::translateSourceLocation(getCursorContext(C), L);
4469 }
4470
4471 if (C.kind == CXCursor_MacroExpansion) {
4472 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004473 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 return cxloc::translateSourceLocation(getCursorContext(C), L);
4475 }
4476
4477 if (C.kind == CXCursor_MacroDefinition) {
4478 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4479 return cxloc::translateSourceLocation(getCursorContext(C), L);
4480 }
4481
4482 if (C.kind == CXCursor_InclusionDirective) {
4483 SourceLocation L
4484 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4485 return cxloc::translateSourceLocation(getCursorContext(C), L);
4486 }
4487
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004488 if (clang_isAttribute(C.kind)) {
4489 SourceLocation L
4490 = cxcursor::getCursorAttr(C)->getLocation();
4491 return cxloc::translateSourceLocation(getCursorContext(C), L);
4492 }
4493
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 if (!clang_isDeclaration(C.kind))
4495 return clang_getNullLocation();
4496
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004497 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 if (!D)
4499 return clang_getNullLocation();
4500
4501 SourceLocation Loc = D->getLocation();
4502 // FIXME: Multiple variables declared in a single declaration
4503 // currently lack the information needed to correctly determine their
4504 // ranges when accounting for the type-specifier. We use context
4505 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4506 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!cxcursor::isFirstInDeclGroup(C))
4509 Loc = VD->getLocation();
4510 }
4511
4512 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 Loc = MD->getSelectorStartLoc();
4515
4516 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4517}
4518
4519} // end extern "C"
4520
4521CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4522 assert(TU);
4523
4524 // Guard against an invalid SourceLocation, or we may assert in one
4525 // of the following calls.
4526 if (SLoc.isInvalid())
4527 return clang_getNullCursor();
4528
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004529 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004530
4531 // Translate the given source location to make it point at the beginning of
4532 // the token under the cursor.
4533 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4534 CXXUnit->getASTContext().getLangOpts());
4535
4536 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4537 if (SLoc.isValid()) {
4538 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4539 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4540 /*VisitPreprocessorLast=*/true,
4541 /*VisitIncludedEntities=*/false,
4542 SourceLocation(SLoc));
4543 CursorVis.visitFileRegion();
4544 }
4545
4546 return Result;
4547}
4548
4549static SourceRange getRawCursorExtent(CXCursor C) {
4550 if (clang_isReference(C.kind)) {
4551 switch (C.kind) {
4552 case CXCursor_ObjCSuperClassRef:
4553 return getCursorObjCSuperClassRef(C).second;
4554
4555 case CXCursor_ObjCProtocolRef:
4556 return getCursorObjCProtocolRef(C).second;
4557
4558 case CXCursor_ObjCClassRef:
4559 return getCursorObjCClassRef(C).second;
4560
4561 case CXCursor_TypeRef:
4562 return getCursorTypeRef(C).second;
4563
4564 case CXCursor_TemplateRef:
4565 return getCursorTemplateRef(C).second;
4566
4567 case CXCursor_NamespaceRef:
4568 return getCursorNamespaceRef(C).second;
4569
4570 case CXCursor_MemberRef:
4571 return getCursorMemberRef(C).second;
4572
4573 case CXCursor_CXXBaseSpecifier:
4574 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4575
4576 case CXCursor_LabelRef:
4577 return getCursorLabelRef(C).second;
4578
4579 case CXCursor_OverloadedDeclRef:
4580 return getCursorOverloadedDeclRef(C).second;
4581
4582 case CXCursor_VariableRef:
4583 return getCursorVariableRef(C).second;
4584
4585 default:
4586 // FIXME: Need a way to enumerate all non-reference cases.
4587 llvm_unreachable("Missed a reference kind");
4588 }
4589 }
4590
4591 if (clang_isExpression(C.kind))
4592 return getCursorExpr(C)->getSourceRange();
4593
4594 if (clang_isStatement(C.kind))
4595 return getCursorStmt(C)->getSourceRange();
4596
4597 if (clang_isAttribute(C.kind))
4598 return getCursorAttr(C)->getRange();
4599
4600 if (C.kind == CXCursor_PreprocessingDirective)
4601 return cxcursor::getCursorPreprocessingDirective(C);
4602
4603 if (C.kind == CXCursor_MacroExpansion) {
4604 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004605 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 return TU->mapRangeFromPreamble(Range);
4607 }
4608
4609 if (C.kind == CXCursor_MacroDefinition) {
4610 ASTUnit *TU = getCursorASTUnit(C);
4611 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4612 return TU->mapRangeFromPreamble(Range);
4613 }
4614
4615 if (C.kind == CXCursor_InclusionDirective) {
4616 ASTUnit *TU = getCursorASTUnit(C);
4617 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4618 return TU->mapRangeFromPreamble(Range);
4619 }
4620
4621 if (C.kind == CXCursor_TranslationUnit) {
4622 ASTUnit *TU = getCursorASTUnit(C);
4623 FileID MainID = TU->getSourceManager().getMainFileID();
4624 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4625 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4626 return SourceRange(Start, End);
4627 }
4628
4629 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004630 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (!D)
4632 return SourceRange();
4633
4634 SourceRange R = D->getSourceRange();
4635 // FIXME: Multiple variables declared in a single declaration
4636 // currently lack the information needed to correctly determine their
4637 // ranges when accounting for the type-specifier. We use context
4638 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4639 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004640 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 if (!cxcursor::isFirstInDeclGroup(C))
4642 R.setBegin(VD->getLocation());
4643 }
4644 return R;
4645 }
4646 return SourceRange();
4647}
4648
4649/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4650/// the decl-specifier-seq for declarations.
4651static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4652 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004653 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!D)
4655 return SourceRange();
4656
4657 SourceRange R = D->getSourceRange();
4658
4659 // Adjust the start of the location for declarations preceded by
4660 // declaration specifiers.
4661 SourceLocation StartLoc;
4662 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4663 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4664 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004665 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4667 StartLoc = TI->getTypeLoc().getLocStart();
4668 }
4669
4670 if (StartLoc.isValid() && R.getBegin().isValid() &&
4671 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4672 R.setBegin(StartLoc);
4673
4674 // FIXME: Multiple variables declared in a single declaration
4675 // currently lack the information needed to correctly determine their
4676 // ranges when accounting for the type-specifier. We use context
4677 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4678 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004679 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 if (!cxcursor::isFirstInDeclGroup(C))
4681 R.setBegin(VD->getLocation());
4682 }
4683
4684 return R;
4685 }
4686
4687 return getRawCursorExtent(C);
4688}
4689
4690extern "C" {
4691
4692CXSourceRange clang_getCursorExtent(CXCursor C) {
4693 SourceRange R = getRawCursorExtent(C);
4694 if (R.isInvalid())
4695 return clang_getNullRange();
4696
4697 return cxloc::translateSourceRange(getCursorContext(C), R);
4698}
4699
4700CXCursor clang_getCursorReferenced(CXCursor C) {
4701 if (clang_isInvalid(C.kind))
4702 return clang_getNullCursor();
4703
4704 CXTranslationUnit tu = getCursorTU(C);
4705 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004706 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 if (!D)
4708 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004709 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 if (const ObjCPropertyImplDecl *PropImpl =
4712 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4714 return MakeCXCursor(Property, tu);
4715
4716 return C;
4717 }
4718
4719 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004720 const Expr *E = getCursorExpr(C);
4721 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 if (D) {
4723 CXCursor declCursor = MakeCXCursor(D, tu);
4724 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4725 declCursor);
4726 return declCursor;
4727 }
4728
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 return MakeCursorOverloadedDeclRef(Ovl, tu);
4731
4732 return clang_getNullCursor();
4733 }
4734
4735 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004736 const Stmt *S = getCursorStmt(C);
4737 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (LabelDecl *label = Goto->getLabel())
4739 if (LabelStmt *labelS = label->getStmt())
4740 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4741
4742 return clang_getNullCursor();
4743 }
4744
4745 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004746 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 return MakeMacroDefinitionCursor(Def, tu);
4748 }
4749
4750 if (!clang_isReference(C.kind))
4751 return clang_getNullCursor();
4752
4753 switch (C.kind) {
4754 case CXCursor_ObjCSuperClassRef:
4755 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4756
4757 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004758 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4759 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 return MakeCXCursor(Def, tu);
4761
4762 return MakeCXCursor(Prot, tu);
4763 }
4764
4765 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004766 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4767 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 return MakeCXCursor(Def, tu);
4769
4770 return MakeCXCursor(Class, tu);
4771 }
4772
4773 case CXCursor_TypeRef:
4774 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4775
4776 case CXCursor_TemplateRef:
4777 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4778
4779 case CXCursor_NamespaceRef:
4780 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4781
4782 case CXCursor_MemberRef:
4783 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4784
4785 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004786 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4788 tu ));
4789 }
4790
4791 case CXCursor_LabelRef:
4792 // FIXME: We end up faking the "parent" declaration here because we
4793 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004794 return MakeCXCursor(getCursorLabelRef(C).first,
4795 cxtu::getASTUnit(tu)->getASTContext()
4796 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 tu);
4798
4799 case CXCursor_OverloadedDeclRef:
4800 return C;
4801
4802 case CXCursor_VariableRef:
4803 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4804
4805 default:
4806 // We would prefer to enumerate all non-reference cursor kinds here.
4807 llvm_unreachable("Unhandled reference cursor kind");
4808 }
4809}
4810
4811CXCursor clang_getCursorDefinition(CXCursor C) {
4812 if (clang_isInvalid(C.kind))
4813 return clang_getNullCursor();
4814
4815 CXTranslationUnit TU = getCursorTU(C);
4816
4817 bool WasReference = false;
4818 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4819 C = clang_getCursorReferenced(C);
4820 WasReference = true;
4821 }
4822
4823 if (C.kind == CXCursor_MacroExpansion)
4824 return clang_getCursorReferenced(C);
4825
4826 if (!clang_isDeclaration(C.kind))
4827 return clang_getNullCursor();
4828
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004829 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (!D)
4831 return clang_getNullCursor();
4832
4833 switch (D->getKind()) {
4834 // Declaration kinds that don't really separate the notions of
4835 // declaration and definition.
4836 case Decl::Namespace:
4837 case Decl::Typedef:
4838 case Decl::TypeAlias:
4839 case Decl::TypeAliasTemplate:
4840 case Decl::TemplateTypeParm:
4841 case Decl::EnumConstant:
4842 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004843 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 case Decl::IndirectField:
4845 case Decl::ObjCIvar:
4846 case Decl::ObjCAtDefsField:
4847 case Decl::ImplicitParam:
4848 case Decl::ParmVar:
4849 case Decl::NonTypeTemplateParm:
4850 case Decl::TemplateTemplateParm:
4851 case Decl::ObjCCategoryImpl:
4852 case Decl::ObjCImplementation:
4853 case Decl::AccessSpec:
4854 case Decl::LinkageSpec:
4855 case Decl::ObjCPropertyImpl:
4856 case Decl::FileScopeAsm:
4857 case Decl::StaticAssert:
4858 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004859 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 case Decl::Label: // FIXME: Is this right??
4861 case Decl::ClassScopeFunctionSpecialization:
4862 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004863 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 return C;
4865
4866 // Declaration kinds that don't make any sense here, but are
4867 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004868 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 case Decl::TranslationUnit:
4870 break;
4871
4872 // Declaration kinds for which the definition is not resolvable.
4873 case Decl::UnresolvedUsingTypename:
4874 case Decl::UnresolvedUsingValue:
4875 break;
4876
4877 case Decl::UsingDirective:
4878 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4879 TU);
4880
4881 case Decl::NamespaceAlias:
4882 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4883
4884 case Decl::Enum:
4885 case Decl::Record:
4886 case Decl::CXXRecord:
4887 case Decl::ClassTemplateSpecialization:
4888 case Decl::ClassTemplatePartialSpecialization:
4889 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4890 return MakeCXCursor(Def, TU);
4891 return clang_getNullCursor();
4892
4893 case Decl::Function:
4894 case Decl::CXXMethod:
4895 case Decl::CXXConstructor:
4896 case Decl::CXXDestructor:
4897 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004898 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004900 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 return clang_getNullCursor();
4902 }
4903
Larisse Voufo39a1e502013-08-06 01:03:05 +00004904 case Decl::Var:
4905 case Decl::VarTemplateSpecialization:
4906 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004908 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 return MakeCXCursor(Def, TU);
4910 return clang_getNullCursor();
4911 }
4912
4913 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004914 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4916 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4917 return clang_getNullCursor();
4918 }
4919
4920 case Decl::ClassTemplate: {
4921 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4922 ->getDefinition())
4923 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4924 TU);
4925 return clang_getNullCursor();
4926 }
4927
Larisse Voufo39a1e502013-08-06 01:03:05 +00004928 case Decl::VarTemplate: {
4929 if (VarDecl *Def =
4930 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4931 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4932 return clang_getNullCursor();
4933 }
4934
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 case Decl::Using:
4936 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4937 D->getLocation(), TU);
4938
4939 case Decl::UsingShadow:
4940 return clang_getCursorDefinition(
4941 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4942 TU));
4943
4944 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004945 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 if (Method->isThisDeclarationADefinition())
4947 return C;
4948
4949 // Dig out the method definition in the associated
4950 // @implementation, if we have it.
4951 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4954 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4955 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4956 Method->isInstanceMethod()))
4957 if (Def->isThisDeclarationADefinition())
4958 return MakeCXCursor(Def, TU);
4959
4960 return clang_getNullCursor();
4961 }
4962
4963 case Decl::ObjCCategory:
4964 if (ObjCCategoryImplDecl *Impl
4965 = cast<ObjCCategoryDecl>(D)->getImplementation())
4966 return MakeCXCursor(Impl, TU);
4967 return clang_getNullCursor();
4968
4969 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004970 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 return MakeCXCursor(Def, TU);
4972 return clang_getNullCursor();
4973
4974 case Decl::ObjCInterface: {
4975 // There are two notions of a "definition" for an Objective-C
4976 // class: the interface and its implementation. When we resolved a
4977 // reference to an Objective-C class, produce the @interface as
4978 // the definition; when we were provided with the interface,
4979 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004980 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004982 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 return MakeCXCursor(Def, TU);
4984 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4985 return MakeCXCursor(Impl, TU);
4986 return clang_getNullCursor();
4987 }
4988
4989 case Decl::ObjCProperty:
4990 // FIXME: We don't really know where to find the
4991 // ObjCPropertyImplDecls that implement this property.
4992 return clang_getNullCursor();
4993
4994 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004995 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004997 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 return MakeCXCursor(Def, TU);
4999
5000 return clang_getNullCursor();
5001
5002 case Decl::Friend:
5003 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5004 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5005 return clang_getNullCursor();
5006
5007 case Decl::FriendTemplate:
5008 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5009 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5010 return clang_getNullCursor();
5011 }
5012
5013 return clang_getNullCursor();
5014}
5015
5016unsigned clang_isCursorDefinition(CXCursor C) {
5017 if (!clang_isDeclaration(C.kind))
5018 return 0;
5019
5020 return clang_getCursorDefinition(C) == C;
5021}
5022
5023CXCursor clang_getCanonicalCursor(CXCursor C) {
5024 if (!clang_isDeclaration(C.kind))
5025 return C;
5026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 if (const Decl *D = getCursorDecl(C)) {
5028 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5030 return MakeCXCursor(CatD, getCursorTU(C));
5031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005032 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5033 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 return MakeCXCursor(IFD, getCursorTU(C));
5035
5036 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5037 }
5038
5039 return C;
5040}
5041
5042int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5043 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5044}
5045
5046unsigned clang_getNumOverloadedDecls(CXCursor C) {
5047 if (C.kind != CXCursor_OverloadedDeclRef)
5048 return 0;
5049
5050 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005051 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 return E->getNumDecls();
5053
5054 if (OverloadedTemplateStorage *S
5055 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5056 return S->size();
5057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005058 const Decl *D = Storage.get<const Decl *>();
5059 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 return Using->shadow_size();
5061
5062 return 0;
5063}
5064
5065CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5066 if (cursor.kind != CXCursor_OverloadedDeclRef)
5067 return clang_getNullCursor();
5068
5069 if (index >= clang_getNumOverloadedDecls(cursor))
5070 return clang_getNullCursor();
5071
5072 CXTranslationUnit TU = getCursorTU(cursor);
5073 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 return MakeCXCursor(E->decls_begin()[index], TU);
5076
5077 if (OverloadedTemplateStorage *S
5078 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5079 return MakeCXCursor(S->begin()[index], TU);
5080
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005081 const Decl *D = Storage.get<const Decl *>();
5082 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 // FIXME: This is, unfortunately, linear time.
5084 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5085 std::advance(Pos, index);
5086 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5087 }
5088
5089 return clang_getNullCursor();
5090}
5091
5092void clang_getDefinitionSpellingAndExtent(CXCursor C,
5093 const char **startBuf,
5094 const char **endBuf,
5095 unsigned *startLine,
5096 unsigned *startColumn,
5097 unsigned *endLine,
5098 unsigned *endColumn) {
5099 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005100 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5102
5103 SourceManager &SM = FD->getASTContext().getSourceManager();
5104 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5105 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5106 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5107 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5108 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5109 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5110}
5111
5112
5113CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5114 unsigned PieceIndex) {
5115 RefNamePieces Pieces;
5116
5117 switch (C.kind) {
5118 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005119 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5121 E->getQualifierLoc().getSourceRange());
5122 break;
5123
5124 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005125 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5127 E->getQualifierLoc().getSourceRange(),
5128 E->getOptionalExplicitTemplateArgs());
5129 break;
5130
5131 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005132 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005134 const Expr *Callee = OCE->getCallee();
5135 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 Callee = ICE->getSubExpr();
5137
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005138 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5140 DRE->getQualifierLoc().getSourceRange());
5141 }
5142 break;
5143
5144 default:
5145 break;
5146 }
5147
5148 if (Pieces.empty()) {
5149 if (PieceIndex == 0)
5150 return clang_getCursorExtent(C);
5151 } else if (PieceIndex < Pieces.size()) {
5152 SourceRange R = Pieces[PieceIndex];
5153 if (R.isValid())
5154 return cxloc::translateSourceRange(getCursorContext(C), R);
5155 }
5156
5157 return clang_getNullRange();
5158}
5159
5160void clang_enableStackTraces(void) {
5161 llvm::sys::PrintStackTraceOnErrorSignal();
5162}
5163
5164void clang_executeOnThread(void (*fn)(void*), void *user_data,
5165 unsigned stack_size) {
5166 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5167}
5168
5169} // end: extern "C"
5170
5171//===----------------------------------------------------------------------===//
5172// Token-based Operations.
5173//===----------------------------------------------------------------------===//
5174
5175/* CXToken layout:
5176 * int_data[0]: a CXTokenKind
5177 * int_data[1]: starting token location
5178 * int_data[2]: token length
5179 * int_data[3]: reserved
5180 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5181 * otherwise unused.
5182 */
5183extern "C" {
5184
5185CXTokenKind clang_getTokenKind(CXToken CXTok) {
5186 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5187}
5188
5189CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5190 switch (clang_getTokenKind(CXTok)) {
5191 case CXToken_Identifier:
5192 case CXToken_Keyword:
5193 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005194 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 ->getNameStart());
5196
5197 case CXToken_Literal: {
5198 // We have stashed the starting pointer in the ptr_data field. Use it.
5199 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005200 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 }
5202
5203 case CXToken_Punctuation:
5204 case CXToken_Comment:
5205 break;
5206 }
5207
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005208 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005209 LOG_BAD_TU(TU);
5210 return cxstring::createEmpty();
5211 }
5212
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 // We have to find the starting buffer pointer the hard way, by
5214 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005217 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005218
5219 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5220 std::pair<FileID, unsigned> LocInfo
5221 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5222 bool Invalid = false;
5223 StringRef Buffer
5224 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5225 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005226 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005227
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005228 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005229}
5230
5231CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005232 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005233 LOG_BAD_TU(TU);
5234 return clang_getNullLocation();
5235 }
5236
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005237 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 if (!CXXUnit)
5239 return clang_getNullLocation();
5240
5241 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5242 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5243}
5244
5245CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005246 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005247 LOG_BAD_TU(TU);
5248 return clang_getNullRange();
5249 }
5250
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005251 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 if (!CXXUnit)
5253 return clang_getNullRange();
5254
5255 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5256 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5257}
5258
5259static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5260 SmallVectorImpl<CXToken> &CXTokens) {
5261 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5262 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005263 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005265 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005266
5267 // Cannot tokenize across files.
5268 if (BeginLocInfo.first != EndLocInfo.first)
5269 return;
5270
5271 // Create a lexer
5272 bool Invalid = false;
5273 StringRef Buffer
5274 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5275 if (Invalid)
5276 return;
5277
5278 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5279 CXXUnit->getASTContext().getLangOpts(),
5280 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5281 Lex.SetCommentRetentionState(true);
5282
5283 // Lex tokens until we hit the end of the range.
5284 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5285 Token Tok;
5286 bool previousWasAt = false;
5287 do {
5288 // Lex the next token
5289 Lex.LexFromRawLexer(Tok);
5290 if (Tok.is(tok::eof))
5291 break;
5292
5293 // Initialize the CXToken.
5294 CXToken CXTok;
5295
5296 // - Common fields
5297 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5298 CXTok.int_data[2] = Tok.getLength();
5299 CXTok.int_data[3] = 0;
5300
5301 // - Kind-specific fields
5302 if (Tok.isLiteral()) {
5303 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005304 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 } else if (Tok.is(tok::raw_identifier)) {
5306 // Lookup the identifier to determine whether we have a keyword.
5307 IdentifierInfo *II
5308 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5309
5310 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5311 CXTok.int_data[0] = CXToken_Keyword;
5312 }
5313 else {
5314 CXTok.int_data[0] = Tok.is(tok::identifier)
5315 ? CXToken_Identifier
5316 : CXToken_Keyword;
5317 }
5318 CXTok.ptr_data = II;
5319 } else if (Tok.is(tok::comment)) {
5320 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005321 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 } else {
5323 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005324 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 }
5326 CXTokens.push_back(CXTok);
5327 previousWasAt = Tok.is(tok::at);
5328 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5329}
5330
5331void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5332 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005333 LOG_FUNC_SECTION {
5334 *Log << TU << ' ' << Range;
5335 }
5336
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005338 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 if (NumTokens)
5340 *NumTokens = 0;
5341
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005342 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005343 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005344 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005345 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005346
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005347 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 if (!CXXUnit || !Tokens || !NumTokens)
5349 return;
5350
5351 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5352
5353 SourceRange R = cxloc::translateCXSourceRange(Range);
5354 if (R.isInvalid())
5355 return;
5356
5357 SmallVector<CXToken, 32> CXTokens;
5358 getTokens(CXXUnit, R, CXTokens);
5359
5360 if (CXTokens.empty())
5361 return;
5362
5363 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5364 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5365 *NumTokens = CXTokens.size();
5366}
5367
5368void clang_disposeTokens(CXTranslationUnit TU,
5369 CXToken *Tokens, unsigned NumTokens) {
5370 free(Tokens);
5371}
5372
5373} // end: extern "C"
5374
5375//===----------------------------------------------------------------------===//
5376// Token annotation APIs.
5377//===----------------------------------------------------------------------===//
5378
Guy Benyei11169dd2012-12-18 14:30:41 +00005379static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5380 CXCursor parent,
5381 CXClientData client_data);
5382static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5383 CXClientData client_data);
5384
5385namespace {
5386class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 CXToken *Tokens;
5388 CXCursor *Cursors;
5389 unsigned NumTokens;
5390 unsigned TokIdx;
5391 unsigned PreprocessingTokIdx;
5392 CursorVisitor AnnotateVis;
5393 SourceManager &SrcMgr;
5394 bool HasContextSensitiveKeywords;
5395
5396 struct PostChildrenInfo {
5397 CXCursor Cursor;
5398 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005399 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 unsigned BeforeChildrenTokenIdx;
5401 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005402 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005403
5404 CXToken &getTok(unsigned Idx) {
5405 assert(Idx < NumTokens);
5406 return Tokens[Idx];
5407 }
5408 const CXToken &getTok(unsigned Idx) const {
5409 assert(Idx < NumTokens);
5410 return Tokens[Idx];
5411 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 bool MoreTokens() const { return TokIdx < NumTokens; }
5413 unsigned NextToken() const { return TokIdx; }
5414 void AdvanceToken() { ++TokIdx; }
5415 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005416 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 }
5418 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005419 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 }
5421 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005422 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 }
5424
5425 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005426 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 SourceRange);
5428
5429public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005430 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005431 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005432 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005434 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 AnnotateTokensVisitor, this,
5436 /*VisitPreprocessorLast=*/true,
5437 /*VisitIncludedEntities=*/false,
5438 RegionOfInterest,
5439 /*VisitDeclsOnly=*/false,
5440 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005441 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 HasContextSensitiveKeywords(false) { }
5443
5444 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5445 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5446 bool postVisitChildren(CXCursor cursor);
5447 void AnnotateTokens();
5448
5449 /// \brief Determine whether the annotator saw any cursors that have
5450 /// context-sensitive keywords.
5451 bool hasContextSensitiveKeywords() const {
5452 return HasContextSensitiveKeywords;
5453 }
5454
5455 ~AnnotateTokensWorker() {
5456 assert(PostChildrenInfos.empty());
5457 }
5458};
5459}
5460
5461void AnnotateTokensWorker::AnnotateTokens() {
5462 // Walk the AST within the region of interest, annotating tokens
5463 // along the way.
5464 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005465}
Guy Benyei11169dd2012-12-18 14:30:41 +00005466
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005467static inline void updateCursorAnnotation(CXCursor &Cursor,
5468 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005469 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005471 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005472}
5473
5474/// \brief It annotates and advances tokens with a cursor until the comparison
5475//// between the cursor location and the source range is the same as
5476/// \arg compResult.
5477///
5478/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5479/// Pass RangeOverlap to annotate tokens inside a range.
5480void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5481 RangeComparisonResult compResult,
5482 SourceRange range) {
5483 while (MoreTokens()) {
5484 const unsigned I = NextToken();
5485 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005486 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5487 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005488
5489 SourceLocation TokLoc = GetTokenLoc(I);
5490 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005491 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 AdvanceToken();
5493 continue;
5494 }
5495 break;
5496 }
5497}
5498
5499/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005500/// \returns true if it advanced beyond all macro tokens, false otherwise.
5501bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 CXCursor updateC,
5503 RangeComparisonResult compResult,
5504 SourceRange range) {
5505 assert(MoreTokens());
5506 assert(isFunctionMacroToken(NextToken()) &&
5507 "Should be called only for macro arg tokens");
5508
5509 // This works differently than annotateAndAdvanceTokens; because expanded
5510 // macro arguments can have arbitrary translation-unit source order, we do not
5511 // advance the token index one by one until a token fails the range test.
5512 // We only advance once past all of the macro arg tokens if all of them
5513 // pass the range test. If one of them fails we keep the token index pointing
5514 // at the start of the macro arg tokens so that the failing token will be
5515 // annotated by a subsequent annotation try.
5516
5517 bool atLeastOneCompFail = false;
5518
5519 unsigned I = NextToken();
5520 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5521 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5522 if (TokLoc.isFileID())
5523 continue; // not macro arg token, it's parens or comma.
5524 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5525 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5526 Cursors[I] = updateC;
5527 } else
5528 atLeastOneCompFail = true;
5529 }
5530
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005531 if (atLeastOneCompFail)
5532 return false;
5533
5534 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5535 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005536}
5537
5538enum CXChildVisitResult
5539AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005540 SourceRange cursorRange = getRawCursorExtent(cursor);
5541 if (cursorRange.isInvalid())
5542 return CXChildVisit_Recurse;
5543
5544 if (!HasContextSensitiveKeywords) {
5545 // Objective-C properties can have context-sensitive keywords.
5546 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005547 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5549 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5550 }
5551 // Objective-C methods can have context-sensitive keywords.
5552 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5553 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005554 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5556 if (Method->getObjCDeclQualifier())
5557 HasContextSensitiveKeywords = true;
5558 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005559 for (const auto *P : Method->params()) {
5560 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 HasContextSensitiveKeywords = true;
5562 break;
5563 }
5564 }
5565 }
5566 }
5567 }
5568 // C++ methods can have context-sensitive keywords.
5569 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005570 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5572 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5573 HasContextSensitiveKeywords = true;
5574 }
5575 }
5576 // C++ classes can have context-sensitive keywords.
5577 else if (cursor.kind == CXCursor_StructDecl ||
5578 cursor.kind == CXCursor_ClassDecl ||
5579 cursor.kind == CXCursor_ClassTemplate ||
5580 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005581 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 if (D->hasAttr<FinalAttr>())
5583 HasContextSensitiveKeywords = true;
5584 }
5585 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005586
5587 // Don't override a property annotation with its getter/setter method.
5588 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5589 parent.kind == CXCursor_ObjCPropertyDecl)
5590 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005591
5592 if (clang_isPreprocessing(cursor.kind)) {
5593 // Items in the preprocessing record are kept separate from items in
5594 // declarations, so we keep a separate token index.
5595 unsigned SavedTokIdx = TokIdx;
5596 TokIdx = PreprocessingTokIdx;
5597
5598 // Skip tokens up until we catch up to the beginning of the preprocessing
5599 // entry.
5600 while (MoreTokens()) {
5601 const unsigned I = NextToken();
5602 SourceLocation TokLoc = GetTokenLoc(I);
5603 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5604 case RangeBefore:
5605 AdvanceToken();
5606 continue;
5607 case RangeAfter:
5608 case RangeOverlap:
5609 break;
5610 }
5611 break;
5612 }
5613
5614 // Look at all of the tokens within this range.
5615 while (MoreTokens()) {
5616 const unsigned I = NextToken();
5617 SourceLocation TokLoc = GetTokenLoc(I);
5618 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5619 case RangeBefore:
5620 llvm_unreachable("Infeasible");
5621 case RangeAfter:
5622 break;
5623 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005624 // For macro expansions, just note where the beginning of the macro
5625 // expansion occurs.
5626 if (cursor.kind == CXCursor_MacroExpansion) {
5627 if (TokLoc == cursorRange.getBegin())
5628 Cursors[I] = cursor;
5629 AdvanceToken();
5630 break;
5631 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005632 // We may have already annotated macro names inside macro definitions.
5633 if (Cursors[I].kind != CXCursor_MacroExpansion)
5634 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 continue;
5637 }
5638 break;
5639 }
5640
5641 // Save the preprocessing token index; restore the non-preprocessing
5642 // token index.
5643 PreprocessingTokIdx = TokIdx;
5644 TokIdx = SavedTokIdx;
5645 return CXChildVisit_Recurse;
5646 }
5647
5648 if (cursorRange.isInvalid())
5649 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005650
5651 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 const enum CXCursorKind K = clang_getCursorKind(parent);
5654 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005655 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5656 // Attributes are annotated out-of-order, skip tokens until we reach it.
5657 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 ? clang_getNullCursor() : parent;
5659
5660 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5661
5662 // Avoid having the cursor of an expression "overwrite" the annotation of the
5663 // variable declaration that it belongs to.
5664 // This can happen for C++ constructor expressions whose range generally
5665 // include the variable declaration, e.g.:
5666 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005667 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005668 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005669 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 const unsigned I = NextToken();
5671 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5672 E->getLocStart() == D->getLocation() &&
5673 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005674 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 AdvanceToken();
5676 }
5677 }
5678 }
5679
5680 // Before recursing into the children keep some state that we are going
5681 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5682 // extra work after the child nodes are visited.
5683 // Note that we don't call VisitChildren here to avoid traversing statements
5684 // code-recursively which can blow the stack.
5685
5686 PostChildrenInfo Info;
5687 Info.Cursor = cursor;
5688 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005689 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 Info.BeforeChildrenTokenIdx = NextToken();
5691 PostChildrenInfos.push_back(Info);
5692
5693 return CXChildVisit_Recurse;
5694}
5695
5696bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5697 if (PostChildrenInfos.empty())
5698 return false;
5699 const PostChildrenInfo &Info = PostChildrenInfos.back();
5700 if (!clang_equalCursors(Info.Cursor, cursor))
5701 return false;
5702
5703 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5704 const unsigned AfterChildren = NextToken();
5705 SourceRange cursorRange = Info.CursorRange;
5706
5707 // Scan the tokens that are at the end of the cursor, but are not captured
5708 // but the child cursors.
5709 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5710
5711 // Scan the tokens that are at the beginning of the cursor, but are not
5712 // capture by the child cursors.
5713 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5714 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5715 break;
5716
5717 Cursors[I] = cursor;
5718 }
5719
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005720 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5721 // encountered the attribute cursor.
5722 if (clang_isAttribute(cursor.kind))
5723 TokIdx = Info.BeforeReachingCursorIdx;
5724
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 PostChildrenInfos.pop_back();
5726 return false;
5727}
5728
5729static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5730 CXCursor parent,
5731 CXClientData client_data) {
5732 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5733}
5734
5735static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5736 CXClientData client_data) {
5737 return static_cast<AnnotateTokensWorker*>(client_data)->
5738 postVisitChildren(cursor);
5739}
5740
5741namespace {
5742
5743/// \brief Uses the macro expansions in the preprocessing record to find
5744/// and mark tokens that are macro arguments. This info is used by the
5745/// AnnotateTokensWorker.
5746class MarkMacroArgTokensVisitor {
5747 SourceManager &SM;
5748 CXToken *Tokens;
5749 unsigned NumTokens;
5750 unsigned CurIdx;
5751
5752public:
5753 MarkMacroArgTokensVisitor(SourceManager &SM,
5754 CXToken *tokens, unsigned numTokens)
5755 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5756
5757 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5758 if (cursor.kind != CXCursor_MacroExpansion)
5759 return CXChildVisit_Continue;
5760
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005761 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 if (macroRange.getBegin() == macroRange.getEnd())
5763 return CXChildVisit_Continue; // it's not a function macro.
5764
5765 for (; CurIdx < NumTokens; ++CurIdx) {
5766 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5767 macroRange.getBegin()))
5768 break;
5769 }
5770
5771 if (CurIdx == NumTokens)
5772 return CXChildVisit_Break;
5773
5774 for (; CurIdx < NumTokens; ++CurIdx) {
5775 SourceLocation tokLoc = getTokenLoc(CurIdx);
5776 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5777 break;
5778
5779 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5780 }
5781
5782 if (CurIdx == NumTokens)
5783 return CXChildVisit_Break;
5784
5785 return CXChildVisit_Continue;
5786 }
5787
5788private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005789 CXToken &getTok(unsigned Idx) {
5790 assert(Idx < NumTokens);
5791 return Tokens[Idx];
5792 }
5793 const CXToken &getTok(unsigned Idx) const {
5794 assert(Idx < NumTokens);
5795 return Tokens[Idx];
5796 }
5797
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005799 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 }
5801
5802 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5803 // The third field is reserved and currently not used. Use it here
5804 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005805 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 }
5807};
5808
5809} // end anonymous namespace
5810
5811static CXChildVisitResult
5812MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5813 CXClientData client_data) {
5814 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5815 parent);
5816}
5817
5818namespace {
5819 struct clang_annotateTokens_Data {
5820 CXTranslationUnit TU;
5821 ASTUnit *CXXUnit;
5822 CXToken *Tokens;
5823 unsigned NumTokens;
5824 CXCursor *Cursors;
5825 };
5826}
5827
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005828/// \brief Used by \c annotatePreprocessorTokens.
5829/// \returns true if lexing was finished, false otherwise.
5830static bool lexNext(Lexer &Lex, Token &Tok,
5831 unsigned &NextIdx, unsigned NumTokens) {
5832 if (NextIdx >= NumTokens)
5833 return true;
5834
5835 ++NextIdx;
5836 Lex.LexFromRawLexer(Tok);
5837 if (Tok.is(tok::eof))
5838 return true;
5839
5840 return false;
5841}
5842
Guy Benyei11169dd2012-12-18 14:30:41 +00005843static void annotatePreprocessorTokens(CXTranslationUnit TU,
5844 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005845 CXCursor *Cursors,
5846 CXToken *Tokens,
5847 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005848 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005849
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005850 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5852 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005853 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005854 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005855 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005856
5857 if (BeginLocInfo.first != EndLocInfo.first)
5858 return;
5859
5860 StringRef Buffer;
5861 bool Invalid = false;
5862 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5863 if (Buffer.empty() || Invalid)
5864 return;
5865
5866 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5867 CXXUnit->getASTContext().getLangOpts(),
5868 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5869 Buffer.end());
5870 Lex.SetCommentRetentionState(true);
5871
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005872 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 // Lex tokens in raw mode until we hit the end of the range, to avoid
5874 // entering #includes or expanding macros.
5875 while (true) {
5876 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005877 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5878 break;
5879 unsigned TokIdx = NextIdx-1;
5880 assert(Tok.getLocation() ==
5881 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005882
5883 reprocess:
5884 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005885 // We have found a preprocessing directive. Annotate the tokens
5886 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 //
5888 // FIXME: Some simple tests here could identify macro definitions and
5889 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005890
5891 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005892 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5893 break;
5894
Craig Topper69186e72014-06-08 08:38:04 +00005895 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005896 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005897 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5898 break;
5899
5900 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005901 IdentifierInfo &II =
5902 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005903 SourceLocation MappedTokLoc =
5904 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5905 MI = getMacroInfo(II, MappedTokLoc, TU);
5906 }
5907 }
5908
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005909 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005911 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5912 finished = true;
5913 break;
5914 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005915 // If we are in a macro definition, check if the token was ever a
5916 // macro name and annotate it if that's the case.
5917 if (MI) {
5918 SourceLocation SaveLoc = Tok.getLocation();
5919 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5920 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5921 Tok.setLocation(SaveLoc);
5922 if (MacroDef)
5923 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5924 Tok.getLocation(), TU);
5925 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005926 } while (!Tok.isAtStartOfLine());
5927
5928 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5929 assert(TokIdx <= LastIdx);
5930 SourceLocation EndLoc =
5931 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5932 CXCursor Cursor =
5933 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5934
5935 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005936 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005937
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005938 if (finished)
5939 break;
5940 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005941 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 }
5943}
5944
5945// This gets run a separate thread to avoid stack blowout.
5946static void clang_annotateTokensImpl(void *UserData) {
5947 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5948 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5949 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5950 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5951 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5952
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005953 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5955 setThreadBackgroundPriority();
5956
5957 // Determine the region of interest, which contains all of the tokens.
5958 SourceRange RegionOfInterest;
5959 RegionOfInterest.setBegin(
5960 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5961 RegionOfInterest.setEnd(
5962 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5963 Tokens[NumTokens-1])));
5964
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 // Relex the tokens within the source range to look for preprocessing
5966 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005967 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005968
5969 // If begin location points inside a macro argument, set it to the expansion
5970 // location so we can have the full context when annotating semantically.
5971 {
5972 SourceManager &SM = CXXUnit->getSourceManager();
5973 SourceLocation Loc =
5974 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5975 if (Loc.isMacroID())
5976 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5977 }
5978
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5980 // Search and mark tokens that are macro argument expansions.
5981 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5982 Tokens, NumTokens);
5983 CursorVisitor MacroArgMarker(TU,
5984 MarkMacroArgTokensVisitorDelegate, &Visitor,
5985 /*VisitPreprocessorLast=*/true,
5986 /*VisitIncludedEntities=*/false,
5987 RegionOfInterest);
5988 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5989 }
5990
5991 // Annotate all of the source locations in the region of interest that map to
5992 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005993 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005994
5995 // FIXME: We use a ridiculous stack size here because the data-recursion
5996 // algorithm uses a large stack frame than the non-data recursive version,
5997 // and AnnotationTokensWorker currently transforms the data-recursion
5998 // algorithm back into a traditional recursion by explicitly calling
5999 // VisitChildren(). We will need to remove this explicit recursive call.
6000 W.AnnotateTokens();
6001
6002 // If we ran into any entities that involve context-sensitive keywords,
6003 // take another pass through the tokens to mark them as such.
6004 if (W.hasContextSensitiveKeywords()) {
6005 for (unsigned I = 0; I != NumTokens; ++I) {
6006 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6007 continue;
6008
6009 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6010 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006011 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6013 if (Property->getPropertyAttributesAsWritten() != 0 &&
6014 llvm::StringSwitch<bool>(II->getName())
6015 .Case("readonly", true)
6016 .Case("assign", true)
6017 .Case("unsafe_unretained", true)
6018 .Case("readwrite", true)
6019 .Case("retain", true)
6020 .Case("copy", true)
6021 .Case("nonatomic", true)
6022 .Case("atomic", true)
6023 .Case("getter", true)
6024 .Case("setter", true)
6025 .Case("strong", true)
6026 .Case("weak", true)
6027 .Default(false))
6028 Tokens[I].int_data[0] = CXToken_Keyword;
6029 }
6030 continue;
6031 }
6032
6033 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6034 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6035 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6036 if (llvm::StringSwitch<bool>(II->getName())
6037 .Case("in", true)
6038 .Case("out", true)
6039 .Case("inout", true)
6040 .Case("oneway", true)
6041 .Case("bycopy", true)
6042 .Case("byref", true)
6043 .Default(false))
6044 Tokens[I].int_data[0] = CXToken_Keyword;
6045 continue;
6046 }
6047
6048 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6049 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6050 Tokens[I].int_data[0] = CXToken_Keyword;
6051 continue;
6052 }
6053 }
6054 }
6055}
6056
6057extern "C" {
6058
6059void clang_annotateTokens(CXTranslationUnit TU,
6060 CXToken *Tokens, unsigned NumTokens,
6061 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006062 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006063 LOG_BAD_TU(TU);
6064 return;
6065 }
6066 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006067 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006068 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006069 }
6070
6071 LOG_FUNC_SECTION {
6072 *Log << TU << ' ';
6073 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6074 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6075 *Log << clang_getRange(bloc, eloc);
6076 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006077
6078 // Any token we don't specifically annotate will have a NULL cursor.
6079 CXCursor C = clang_getNullCursor();
6080 for (unsigned I = 0; I != NumTokens; ++I)
6081 Cursors[I] = C;
6082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006083 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006084 if (!CXXUnit)
6085 return;
6086
6087 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6088
6089 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6090 llvm::CrashRecoveryContext CRC;
6091 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6092 GetSafetyThreadStackSize() * 2)) {
6093 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6094 }
6095}
6096
6097} // end: extern "C"
6098
6099//===----------------------------------------------------------------------===//
6100// Operations for querying linkage of a cursor.
6101//===----------------------------------------------------------------------===//
6102
6103extern "C" {
6104CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6105 if (!clang_isDeclaration(cursor.kind))
6106 return CXLinkage_Invalid;
6107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006108 const Decl *D = cxcursor::getCursorDecl(cursor);
6109 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006110 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006111 case NoLinkage:
6112 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 case InternalLinkage: return CXLinkage_Internal;
6114 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6115 case ExternalLinkage: return CXLinkage_External;
6116 };
6117
6118 return CXLinkage_Invalid;
6119}
6120} // end: extern "C"
6121
6122//===----------------------------------------------------------------------===//
6123// Operations for querying language of a cursor.
6124//===----------------------------------------------------------------------===//
6125
6126static CXLanguageKind getDeclLanguage(const Decl *D) {
6127 if (!D)
6128 return CXLanguage_C;
6129
6130 switch (D->getKind()) {
6131 default:
6132 break;
6133 case Decl::ImplicitParam:
6134 case Decl::ObjCAtDefsField:
6135 case Decl::ObjCCategory:
6136 case Decl::ObjCCategoryImpl:
6137 case Decl::ObjCCompatibleAlias:
6138 case Decl::ObjCImplementation:
6139 case Decl::ObjCInterface:
6140 case Decl::ObjCIvar:
6141 case Decl::ObjCMethod:
6142 case Decl::ObjCProperty:
6143 case Decl::ObjCPropertyImpl:
6144 case Decl::ObjCProtocol:
6145 return CXLanguage_ObjC;
6146 case Decl::CXXConstructor:
6147 case Decl::CXXConversion:
6148 case Decl::CXXDestructor:
6149 case Decl::CXXMethod:
6150 case Decl::CXXRecord:
6151 case Decl::ClassTemplate:
6152 case Decl::ClassTemplatePartialSpecialization:
6153 case Decl::ClassTemplateSpecialization:
6154 case Decl::Friend:
6155 case Decl::FriendTemplate:
6156 case Decl::FunctionTemplate:
6157 case Decl::LinkageSpec:
6158 case Decl::Namespace:
6159 case Decl::NamespaceAlias:
6160 case Decl::NonTypeTemplateParm:
6161 case Decl::StaticAssert:
6162 case Decl::TemplateTemplateParm:
6163 case Decl::TemplateTypeParm:
6164 case Decl::UnresolvedUsingTypename:
6165 case Decl::UnresolvedUsingValue:
6166 case Decl::Using:
6167 case Decl::UsingDirective:
6168 case Decl::UsingShadow:
6169 return CXLanguage_CPlusPlus;
6170 }
6171
6172 return CXLanguage_C;
6173}
6174
6175extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006176
6177static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6178 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6179 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006180
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006181 switch (D->getAvailability()) {
6182 case AR_Available:
6183 case AR_NotYetIntroduced:
6184 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006185 return getCursorAvailabilityForDecl(
6186 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006187 return CXAvailability_Available;
6188
6189 case AR_Deprecated:
6190 return CXAvailability_Deprecated;
6191
6192 case AR_Unavailable:
6193 return CXAvailability_NotAvailable;
6194 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006195
6196 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006197}
6198
Guy Benyei11169dd2012-12-18 14:30:41 +00006199enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6200 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006201 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6202 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006203
6204 return CXAvailability_Available;
6205}
6206
6207static CXVersion convertVersion(VersionTuple In) {
6208 CXVersion Out = { -1, -1, -1 };
6209 if (In.empty())
6210 return Out;
6211
6212 Out.Major = In.getMajor();
6213
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006214 Optional<unsigned> Minor = In.getMinor();
6215 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006216 Out.Minor = *Minor;
6217 else
6218 return Out;
6219
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006220 Optional<unsigned> Subminor = In.getSubminor();
6221 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 Out.Subminor = *Subminor;
6223
6224 return Out;
6225}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006226
6227static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6228 int *always_deprecated,
6229 CXString *deprecated_message,
6230 int *always_unavailable,
6231 CXString *unavailable_message,
6232 CXPlatformAvailability *availability,
6233 int availability_size) {
6234 bool HadAvailAttr = false;
6235 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006236 for (auto A : D->attrs()) {
6237 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006238 HadAvailAttr = true;
6239 if (always_deprecated)
6240 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006241 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006242 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006243 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006244 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006245 continue;
6246 }
6247
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006248 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006249 HadAvailAttr = true;
6250 if (always_unavailable)
6251 *always_unavailable = 1;
6252 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006253 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006254 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6255 }
6256 continue;
6257 }
6258
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006259 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006260 HadAvailAttr = true;
6261 if (N < availability_size) {
6262 availability[N].Platform
6263 = cxstring::createDup(Avail->getPlatform()->getName());
6264 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6265 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6266 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6267 availability[N].Unavailable = Avail->getUnavailable();
6268 availability[N].Message = cxstring::createDup(Avail->getMessage());
6269 }
6270 ++N;
6271 }
6272 }
6273
6274 if (!HadAvailAttr)
6275 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6276 return getCursorPlatformAvailabilityForDecl(
6277 cast<Decl>(EnumConst->getDeclContext()),
6278 always_deprecated,
6279 deprecated_message,
6280 always_unavailable,
6281 unavailable_message,
6282 availability,
6283 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006284
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006285 return N;
6286}
6287
Guy Benyei11169dd2012-12-18 14:30:41 +00006288int clang_getCursorPlatformAvailability(CXCursor cursor,
6289 int *always_deprecated,
6290 CXString *deprecated_message,
6291 int *always_unavailable,
6292 CXString *unavailable_message,
6293 CXPlatformAvailability *availability,
6294 int availability_size) {
6295 if (always_deprecated)
6296 *always_deprecated = 0;
6297 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006298 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 if (always_unavailable)
6300 *always_unavailable = 0;
6301 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006302 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006303
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 if (!clang_isDeclaration(cursor.kind))
6305 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006306
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006307 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 if (!D)
6309 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006310
6311 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6312 deprecated_message,
6313 always_unavailable,
6314 unavailable_message,
6315 availability,
6316 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006317}
6318
6319void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6320 clang_disposeString(availability->Platform);
6321 clang_disposeString(availability->Message);
6322}
6323
6324CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6325 if (clang_isDeclaration(cursor.kind))
6326 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6327
6328 return CXLanguage_Invalid;
6329}
6330
6331 /// \brief If the given cursor is the "templated" declaration
6332 /// descibing a class or function template, return the class or
6333 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006334static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006336 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006337
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006338 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6340 return FunTmpl;
6341
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006342 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006343 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6344 return ClassTmpl;
6345
6346 return D;
6347}
6348
6349CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6350 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006351 if (const Decl *D = getCursorDecl(cursor)) {
6352 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006353 if (!DC)
6354 return clang_getNullCursor();
6355
6356 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6357 getCursorTU(cursor));
6358 }
6359 }
6360
6361 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006362 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 return MakeCXCursor(D, getCursorTU(cursor));
6364 }
6365
6366 return clang_getNullCursor();
6367}
6368
6369CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6370 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006371 if (const Decl *D = getCursorDecl(cursor)) {
6372 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006373 if (!DC)
6374 return clang_getNullCursor();
6375
6376 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6377 getCursorTU(cursor));
6378 }
6379 }
6380
6381 // FIXME: Note that we can't easily compute the lexical context of a
6382 // statement or expression, so we return nothing.
6383 return clang_getNullCursor();
6384}
6385
6386CXFile clang_getIncludedFile(CXCursor cursor) {
6387 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006388 return nullptr;
6389
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006390 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006391 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006392}
6393
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006394unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6395 if (C.kind != CXCursor_ObjCPropertyDecl)
6396 return CXObjCPropertyAttr_noattr;
6397
6398 unsigned Result = CXObjCPropertyAttr_noattr;
6399 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6400 ObjCPropertyDecl::PropertyAttributeKind Attr =
6401 PD->getPropertyAttributesAsWritten();
6402
6403#define SET_CXOBJCPROP_ATTR(A) \
6404 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6405 Result |= CXObjCPropertyAttr_##A
6406 SET_CXOBJCPROP_ATTR(readonly);
6407 SET_CXOBJCPROP_ATTR(getter);
6408 SET_CXOBJCPROP_ATTR(assign);
6409 SET_CXOBJCPROP_ATTR(readwrite);
6410 SET_CXOBJCPROP_ATTR(retain);
6411 SET_CXOBJCPROP_ATTR(copy);
6412 SET_CXOBJCPROP_ATTR(nonatomic);
6413 SET_CXOBJCPROP_ATTR(setter);
6414 SET_CXOBJCPROP_ATTR(atomic);
6415 SET_CXOBJCPROP_ATTR(weak);
6416 SET_CXOBJCPROP_ATTR(strong);
6417 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6418#undef SET_CXOBJCPROP_ATTR
6419
6420 return Result;
6421}
6422
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006423unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6424 if (!clang_isDeclaration(C.kind))
6425 return CXObjCDeclQualifier_None;
6426
6427 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6428 const Decl *D = getCursorDecl(C);
6429 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6430 QT = MD->getObjCDeclQualifier();
6431 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6432 QT = PD->getObjCDeclQualifier();
6433 if (QT == Decl::OBJC_TQ_None)
6434 return CXObjCDeclQualifier_None;
6435
6436 unsigned Result = CXObjCDeclQualifier_None;
6437 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6438 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6439 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6440 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6441 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6442 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6443
6444 return Result;
6445}
6446
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006447unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6448 if (!clang_isDeclaration(C.kind))
6449 return 0;
6450
6451 const Decl *D = getCursorDecl(C);
6452 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6453 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6454 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6455 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6456
6457 return 0;
6458}
6459
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006460unsigned clang_Cursor_isVariadic(CXCursor C) {
6461 if (!clang_isDeclaration(C.kind))
6462 return 0;
6463
6464 const Decl *D = getCursorDecl(C);
6465 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6466 return FD->isVariadic();
6467 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6468 return MD->isVariadic();
6469
6470 return 0;
6471}
6472
Guy Benyei11169dd2012-12-18 14:30:41 +00006473CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6474 if (!clang_isDeclaration(C.kind))
6475 return clang_getNullRange();
6476
6477 const Decl *D = getCursorDecl(C);
6478 ASTContext &Context = getCursorContext(C);
6479 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6480 if (!RC)
6481 return clang_getNullRange();
6482
6483 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6484}
6485
6486CXString clang_Cursor_getRawCommentText(CXCursor C) {
6487 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006488 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006489
6490 const Decl *D = getCursorDecl(C);
6491 ASTContext &Context = getCursorContext(C);
6492 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6493 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6494 StringRef();
6495
6496 // Don't duplicate the string because RawText points directly into source
6497 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006498 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006499}
6500
6501CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6502 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006503 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006504
6505 const Decl *D = getCursorDecl(C);
6506 const ASTContext &Context = getCursorContext(C);
6507 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6508
6509 if (RC) {
6510 StringRef BriefText = RC->getBriefText(Context);
6511
6512 // Don't duplicate the string because RawComment ensures that this memory
6513 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006514 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 }
6516
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006517 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006518}
6519
Guy Benyei11169dd2012-12-18 14:30:41 +00006520CXModule clang_Cursor_getModule(CXCursor C) {
6521 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006522 if (const ImportDecl *ImportD =
6523 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 return ImportD->getImportedModule();
6525 }
6526
Craig Topper69186e72014-06-08 08:38:04 +00006527 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006528}
6529
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006530CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6531 if (isNotUsableTU(TU)) {
6532 LOG_BAD_TU(TU);
6533 return nullptr;
6534 }
6535 if (!File)
6536 return nullptr;
6537 FileEntry *FE = static_cast<FileEntry *>(File);
6538
6539 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6540 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6541 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6542
6543 if (Module *Mod = Header.getModule()) {
6544 if (Header.getRole() != ModuleMap::ExcludedHeader)
6545 return Mod;
6546 }
6547 return nullptr;
6548}
6549
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006550CXFile clang_Module_getASTFile(CXModule CXMod) {
6551 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006552 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006553 Module *Mod = static_cast<Module*>(CXMod);
6554 return const_cast<FileEntry *>(Mod->getASTFile());
6555}
6556
Guy Benyei11169dd2012-12-18 14:30:41 +00006557CXModule clang_Module_getParent(CXModule CXMod) {
6558 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006559 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 Module *Mod = static_cast<Module*>(CXMod);
6561 return Mod->Parent;
6562}
6563
6564CXString clang_Module_getName(CXModule CXMod) {
6565 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006566 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006567 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006568 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006569}
6570
6571CXString clang_Module_getFullName(CXModule CXMod) {
6572 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006573 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006574 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006575 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006576}
6577
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006578int clang_Module_isSystem(CXModule CXMod) {
6579 if (!CXMod)
6580 return 0;
6581 Module *Mod = static_cast<Module*>(CXMod);
6582 return Mod->IsSystem;
6583}
6584
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006585unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6586 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006587 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006588 LOG_BAD_TU(TU);
6589 return 0;
6590 }
6591 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006592 return 0;
6593 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006594 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6595 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6596 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006597}
6598
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006599CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6600 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006601 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006602 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006603 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006604 }
6605 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006606 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006608 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006609
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006610 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6611 if (Index < TopHeaders.size())
6612 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006613
Craig Topper69186e72014-06-08 08:38:04 +00006614 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006615}
6616
6617} // end: extern "C"
6618
6619//===----------------------------------------------------------------------===//
6620// C++ AST instrospection.
6621//===----------------------------------------------------------------------===//
6622
6623extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006624unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6625 if (!clang_isDeclaration(C.kind))
6626 return 0;
6627
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006628 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006629 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006630 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006631 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6632}
6633
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006634unsigned clang_CXXMethod_isConst(CXCursor C) {
6635 if (!clang_isDeclaration(C.kind))
6636 return 0;
6637
6638 const Decl *D = cxcursor::getCursorDecl(C);
6639 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006640 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006641 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6642}
6643
Guy Benyei11169dd2012-12-18 14:30:41 +00006644unsigned clang_CXXMethod_isStatic(CXCursor C) {
6645 if (!clang_isDeclaration(C.kind))
6646 return 0;
6647
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006648 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006649 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006650 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006651 return (Method && Method->isStatic()) ? 1 : 0;
6652}
6653
6654unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6655 if (!clang_isDeclaration(C.kind))
6656 return 0;
6657
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006658 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006659 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006660 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 return (Method && Method->isVirtual()) ? 1 : 0;
6662}
6663} // end: extern "C"
6664
6665//===----------------------------------------------------------------------===//
6666// Attribute introspection.
6667//===----------------------------------------------------------------------===//
6668
6669extern "C" {
6670CXType clang_getIBOutletCollectionType(CXCursor C) {
6671 if (C.kind != CXCursor_IBOutletCollectionAttr)
6672 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6673
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006674 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6676
6677 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6678}
6679} // end: extern "C"
6680
6681//===----------------------------------------------------------------------===//
6682// Inspecting memory usage.
6683//===----------------------------------------------------------------------===//
6684
6685typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6686
6687static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6688 enum CXTUResourceUsageKind k,
6689 unsigned long amount) {
6690 CXTUResourceUsageEntry entry = { k, amount };
6691 entries.push_back(entry);
6692}
6693
6694extern "C" {
6695
6696const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6697 const char *str = "";
6698 switch (kind) {
6699 case CXTUResourceUsage_AST:
6700 str = "ASTContext: expressions, declarations, and types";
6701 break;
6702 case CXTUResourceUsage_Identifiers:
6703 str = "ASTContext: identifiers";
6704 break;
6705 case CXTUResourceUsage_Selectors:
6706 str = "ASTContext: selectors";
6707 break;
6708 case CXTUResourceUsage_GlobalCompletionResults:
6709 str = "Code completion: cached global results";
6710 break;
6711 case CXTUResourceUsage_SourceManagerContentCache:
6712 str = "SourceManager: content cache allocator";
6713 break;
6714 case CXTUResourceUsage_AST_SideTables:
6715 str = "ASTContext: side tables";
6716 break;
6717 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6718 str = "SourceManager: malloc'ed memory buffers";
6719 break;
6720 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6721 str = "SourceManager: mmap'ed memory buffers";
6722 break;
6723 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6724 str = "ExternalASTSource: malloc'ed memory buffers";
6725 break;
6726 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6727 str = "ExternalASTSource: mmap'ed memory buffers";
6728 break;
6729 case CXTUResourceUsage_Preprocessor:
6730 str = "Preprocessor: malloc'ed memory";
6731 break;
6732 case CXTUResourceUsage_PreprocessingRecord:
6733 str = "Preprocessor: PreprocessingRecord";
6734 break;
6735 case CXTUResourceUsage_SourceManager_DataStructures:
6736 str = "SourceManager: data structures and tables";
6737 break;
6738 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6739 str = "Preprocessor: header search tables";
6740 break;
6741 }
6742 return str;
6743}
6744
6745CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006746 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006747 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006748 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006749 return usage;
6750 }
6751
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006752 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006753 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006754 ASTContext &astContext = astUnit->getASTContext();
6755
6756 // How much memory is used by AST nodes and types?
6757 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6758 (unsigned long) astContext.getASTAllocatedMemory());
6759
6760 // How much memory is used by identifiers?
6761 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6762 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6763
6764 // How much memory is used for selectors?
6765 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6766 (unsigned long) astContext.Selectors.getTotalMemory());
6767
6768 // How much memory is used by ASTContext's side tables?
6769 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6770 (unsigned long) astContext.getSideTableAllocatedMemory());
6771
6772 // How much memory is used for caching global code completion results?
6773 unsigned long completionBytes = 0;
6774 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006775 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 completionBytes = completionAllocator->getTotalMemory();
6777 }
6778 createCXTUResourceUsageEntry(*entries,
6779 CXTUResourceUsage_GlobalCompletionResults,
6780 completionBytes);
6781
6782 // How much memory is being used by SourceManager's content cache?
6783 createCXTUResourceUsageEntry(*entries,
6784 CXTUResourceUsage_SourceManagerContentCache,
6785 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6786
6787 // How much memory is being used by the MemoryBuffer's in SourceManager?
6788 const SourceManager::MemoryBufferSizes &srcBufs =
6789 astUnit->getSourceManager().getMemoryBufferSizes();
6790
6791 createCXTUResourceUsageEntry(*entries,
6792 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6793 (unsigned long) srcBufs.malloc_bytes);
6794 createCXTUResourceUsageEntry(*entries,
6795 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6796 (unsigned long) srcBufs.mmap_bytes);
6797 createCXTUResourceUsageEntry(*entries,
6798 CXTUResourceUsage_SourceManager_DataStructures,
6799 (unsigned long) astContext.getSourceManager()
6800 .getDataStructureSizes());
6801
6802 // How much memory is being used by the ExternalASTSource?
6803 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6804 const ExternalASTSource::MemoryBufferSizes &sizes =
6805 esrc->getMemoryBufferSizes();
6806
6807 createCXTUResourceUsageEntry(*entries,
6808 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6809 (unsigned long) sizes.malloc_bytes);
6810 createCXTUResourceUsageEntry(*entries,
6811 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6812 (unsigned long) sizes.mmap_bytes);
6813 }
6814
6815 // How much memory is being used by the Preprocessor?
6816 Preprocessor &pp = astUnit->getPreprocessor();
6817 createCXTUResourceUsageEntry(*entries,
6818 CXTUResourceUsage_Preprocessor,
6819 pp.getTotalMemory());
6820
6821 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6822 createCXTUResourceUsageEntry(*entries,
6823 CXTUResourceUsage_PreprocessingRecord,
6824 pRec->getTotalMemory());
6825 }
6826
6827 createCXTUResourceUsageEntry(*entries,
6828 CXTUResourceUsage_Preprocessor_HeaderSearch,
6829 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006830
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 CXTUResourceUsage usage = { (void*) entries.get(),
6832 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006833 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006834 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006835 return usage;
6836}
6837
6838void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6839 if (usage.data)
6840 delete (MemUsageEntries*) usage.data;
6841}
6842
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006843CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6844 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006845 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006846 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006847
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006848 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006849 LOG_BAD_TU(TU);
6850 return skipped;
6851 }
6852
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006853 if (!file)
6854 return skipped;
6855
6856 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6857 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6858 if (!ppRec)
6859 return skipped;
6860
6861 ASTContext &Ctx = astUnit->getASTContext();
6862 SourceManager &sm = Ctx.getSourceManager();
6863 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6864 FileID wantedFileID = sm.translateFile(fileEntry);
6865
6866 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6867 std::vector<SourceRange> wantedRanges;
6868 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6869 i != ei; ++i) {
6870 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6871 wantedRanges.push_back(*i);
6872 }
6873
6874 skipped->count = wantedRanges.size();
6875 skipped->ranges = new CXSourceRange[skipped->count];
6876 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6877 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6878
6879 return skipped;
6880}
6881
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006882void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6883 if (ranges) {
6884 delete[] ranges->ranges;
6885 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006886 }
6887}
6888
Guy Benyei11169dd2012-12-18 14:30:41 +00006889} // end extern "C"
6890
6891void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6892 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6893 for (unsigned I = 0; I != Usage.numEntries; ++I)
6894 fprintf(stderr, " %s: %lu\n",
6895 clang_getTUResourceUsageName(Usage.entries[I].kind),
6896 Usage.entries[I].amount);
6897
6898 clang_disposeCXTUResourceUsage(Usage);
6899}
6900
6901//===----------------------------------------------------------------------===//
6902// Misc. utility functions.
6903//===----------------------------------------------------------------------===//
6904
6905/// Default to using an 8 MB stack size on "safety" threads.
6906static unsigned SafetyStackThreadSize = 8 << 20;
6907
6908namespace clang {
6909
6910bool RunSafely(llvm::CrashRecoveryContext &CRC,
6911 void (*Fn)(void*), void *UserData,
6912 unsigned Size) {
6913 if (!Size)
6914 Size = GetSafetyThreadStackSize();
6915 if (Size)
6916 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6917 return CRC.RunSafely(Fn, UserData);
6918}
6919
6920unsigned GetSafetyThreadStackSize() {
6921 return SafetyStackThreadSize;
6922}
6923
6924void SetSafetyThreadStackSize(unsigned Value) {
6925 SafetyStackThreadSize = Value;
6926}
6927
6928}
6929
6930void clang::setThreadBackgroundPriority() {
6931 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6932 return;
6933
Alp Toker1a86ad22014-07-06 06:24:00 +00006934#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006935 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6936#endif
6937}
6938
6939void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6940 if (!Unit)
6941 return;
6942
6943 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6944 DEnd = Unit->stored_diag_end();
6945 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006946 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006947 CXString Msg = clang_formatDiagnostic(&Diag,
6948 clang_defaultDiagnosticDisplayOptions());
6949 fprintf(stderr, "%s\n", clang_getCString(Msg));
6950 clang_disposeString(Msg);
6951 }
6952#ifdef LLVM_ON_WIN32
6953 // On Windows, force a flush, since there may be multiple copies of
6954 // stderr and stdout in the file system, all with different buffers
6955 // but writing to the same device.
6956 fflush(stderr);
6957#endif
6958}
6959
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006960MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6961 SourceLocation MacroDefLoc,
6962 CXTranslationUnit TU){
6963 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006964 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006965 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006966 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006967
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006968 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006969 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006970 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006971 if (MD) {
6972 for (MacroDirective::DefInfo
6973 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6974 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6975 return Def.getMacroInfo();
6976 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006977 }
6978
Craig Topper69186e72014-06-08 08:38:04 +00006979 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006980}
6981
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006982const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6983 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006984 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006985 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006986 const IdentifierInfo *II = MacroDef->getName();
6987 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006988 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006989
6990 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6991}
6992
6993MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6994 const Token &Tok,
6995 CXTranslationUnit TU) {
6996 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006997 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006998 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000
7001 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007002 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007003 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7004 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007005 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007006
7007 // Check that the token is inside the definition and not its argument list.
7008 SourceManager &SM = Unit->getSourceManager();
7009 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007010 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007011 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007012 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007013
7014 Preprocessor &PP = Unit->getPreprocessor();
7015 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7016 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007017 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007018
Alp Toker2d57cea2014-05-17 04:53:25 +00007019 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007020 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007021 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007022
7023 // Check that the identifier is not one of the macro arguments.
7024 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007025 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007026
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007027 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7028 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007029 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007030
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007031 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007032}
7033
7034MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7035 SourceLocation Loc,
7036 CXTranslationUnit TU) {
7037 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007038 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007039
7040 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007041 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007042 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007043 Preprocessor &PP = Unit->getPreprocessor();
7044 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007045 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007046 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7047 Token Tok;
7048 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007049 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007050
7051 return checkForMacroInMacroDefinition(MI, Tok, TU);
7052}
7053
Guy Benyei11169dd2012-12-18 14:30:41 +00007054extern "C" {
7055
7056CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007057 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007058}
7059
7060} // end: extern "C"
7061
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007062Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7063 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007064 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007065 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007066 if (Unit->isMainFileAST())
7067 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007068 return *this;
7069 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007070 } else {
7071 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007072 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007073 return *this;
7074}
7075
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007076Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7077 *this << FE->getName();
7078 return *this;
7079}
7080
7081Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7082 CXString cursorName = clang_getCursorDisplayName(cursor);
7083 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7084 clang_disposeString(cursorName);
7085 return *this;
7086}
7087
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007088Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7089 CXFile File;
7090 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007091 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007092 CXString FileName = clang_getFileName(File);
7093 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7094 clang_disposeString(FileName);
7095 return *this;
7096}
7097
7098Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7099 CXSourceLocation BLoc = clang_getRangeStart(range);
7100 CXSourceLocation ELoc = clang_getRangeEnd(range);
7101
7102 CXFile BFile;
7103 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007104 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007105
7106 CXFile EFile;
7107 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007108 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007109
7110 CXString BFileName = clang_getFileName(BFile);
7111 if (BFile == EFile) {
7112 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7113 BLine, BColumn, ELine, EColumn);
7114 } else {
7115 CXString EFileName = clang_getFileName(EFile);
7116 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7117 BLine, BColumn)
7118 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7119 ELine, EColumn);
7120 clang_disposeString(EFileName);
7121 }
7122 clang_disposeString(BFileName);
7123 return *this;
7124}
7125
7126Logger &cxindex::Logger::operator<<(CXString Str) {
7127 *this << clang_getCString(Str);
7128 return *this;
7129}
7130
7131Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7132 LogOS << Fmt;
7133 return *this;
7134}
7135
Chandler Carruth37ad2582014-06-27 15:14:39 +00007136static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7137
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007138cxindex::Logger::~Logger() {
7139 LogOS.flush();
7140
Chandler Carruth37ad2582014-06-27 15:14:39 +00007141 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007142
7143 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7144
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007145 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007146 OS << "[libclang:" << Name << ':';
7147
Alp Toker1a86ad22014-07-06 06:24:00 +00007148#ifdef USE_DARWIN_THREADS
7149 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007150 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7151 OS << tid << ':';
7152#endif
7153
7154 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7155 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7156 OS << Msg.str() << '\n';
7157
7158 if (Trace) {
7159 llvm::sys::PrintStackTrace(stderr);
7160 OS << "--------------------------------------------------\n";
7161 }
7162}