blob: 829cab736d793c3b1b9d85f0c97594183ac422f3 [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"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
150 if (R.isTokenRange() && !EndLoc.isInvalid()) {
151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000920bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
921 // Visit the bound, if it's explicit.
922 if (D->hasExplicitBound()) {
923 if (auto TInfo = D->getTypeSourceInfo()) {
924 if (Visit(TInfo->getTypeLoc()))
925 return true;
926 }
927 }
928
929 return false;
930}
931
Guy Benyei11169dd2012-12-18 14:30:41 +0000932bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000933 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000934 if (Visit(TSInfo->getTypeLoc()))
935 return true;
936
Aaron Ballman43b68be2014-03-07 17:50:17 +0000937 for (const auto *P : ND->params()) {
938 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000939 return true;
940 }
941
942 if (ND->isThisDeclarationADefinition() &&
943 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
944 return true;
945
946 return false;
947}
948
949template <typename DeclIt>
950static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
951 SourceManager &SM, SourceLocation EndLoc,
952 SmallVectorImpl<Decl *> &Decls) {
953 DeclIt next = *DI_current;
954 while (++next != DE_current) {
955 Decl *D_next = *next;
956 if (!D_next)
957 break;
958 SourceLocation L = D_next->getLocStart();
959 if (!L.isValid())
960 break;
961 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
962 *DI_current = next;
963 Decls.push_back(D_next);
964 continue;
965 }
966 break;
967 }
968}
969
Guy Benyei11169dd2012-12-18 14:30:41 +0000970bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
971 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
972 // an @implementation can lexically contain Decls that are not properly
973 // nested in the AST. When we identify such cases, we need to retrofit
974 // this nesting here.
975 if (!DI_current && !FileDI_current)
976 return VisitDeclContext(D);
977
978 // Scan the Decls that immediately come after the container
979 // in the current DeclContext. If any fall within the
980 // container's lexical region, stash them into a vector
981 // for later processing.
982 SmallVector<Decl *, 24> DeclsInContainer;
983 SourceLocation EndLoc = D->getSourceRange().getEnd();
984 SourceManager &SM = AU->getSourceManager();
985 if (EndLoc.isValid()) {
986 if (DI_current) {
987 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
988 DeclsInContainer);
989 } else {
990 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
991 DeclsInContainer);
992 }
993 }
994
995 // The common case.
996 if (DeclsInContainer.empty())
997 return VisitDeclContext(D);
998
999 // Get all the Decls in the DeclContext, and sort them with the
1000 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001001 for (auto *SubDecl : D->decls()) {
1002 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1003 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001005 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 }
1007
1008 // Now sort the Decls so that they appear in lexical order.
1009 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001010 [&SM](Decl *A, Decl *B) {
1011 SourceLocation L_A = A->getLocStart();
1012 SourceLocation L_B = B->getLocStart();
1013 assert(L_A.isValid() && L_B.isValid());
1014 return SM.isBeforeInTranslationUnit(L_A, L_B);
1015 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001016
1017 // Now visit the decls.
1018 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1019 E = DeclsInContainer.end(); I != E; ++I) {
1020 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001021 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001022 if (!V.hasValue())
1023 continue;
1024 if (!V.getValue())
1025 return false;
1026 if (Visit(Cursor, true))
1027 return true;
1028 }
1029 return false;
1030}
1031
1032bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1033 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1034 TU)))
1035 return true;
1036
Douglas Gregore9d95f12015-07-07 03:57:35 +00001037 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1038 return true;
1039
Guy Benyei11169dd2012-12-18 14:30:41 +00001040 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1041 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1042 E = ND->protocol_end(); I != E; ++I, ++PL)
1043 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1044 return true;
1045
1046 return VisitObjCContainerDecl(ND);
1047}
1048
1049bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1050 if (!PID->isThisDeclarationADefinition())
1051 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1052
1053 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1054 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1055 E = PID->protocol_end(); I != E; ++I, ++PL)
1056 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1057 return true;
1058
1059 return VisitObjCContainerDecl(PID);
1060}
1061
1062bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1063 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1064 return true;
1065
1066 // FIXME: This implements a workaround with @property declarations also being
1067 // installed in the DeclContext for the @interface. Eventually this code
1068 // should be removed.
1069 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1070 if (!CDecl || !CDecl->IsClassExtension())
1071 return false;
1072
1073 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1074 if (!ID)
1075 return false;
1076
1077 IdentifierInfo *PropertyId = PD->getIdentifier();
1078 ObjCPropertyDecl *prevDecl =
1079 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1080
1081 if (!prevDecl)
1082 return false;
1083
1084 // Visit synthesized methods since they will be skipped when visiting
1085 // the @interface.
1086 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1087 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1088 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1089 return true;
1090
1091 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1092 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1093 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1094 return true;
1095
1096 return false;
1097}
1098
Douglas Gregore9d95f12015-07-07 03:57:35 +00001099bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1100 if (!typeParamList)
1101 return false;
1102
1103 for (auto *typeParam : *typeParamList) {
1104 // Visit the type parameter.
1105 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1106 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001107 }
1108
1109 return false;
1110}
1111
Guy Benyei11169dd2012-12-18 14:30:41 +00001112bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1113 if (!D->isThisDeclarationADefinition()) {
1114 // Forward declaration is treated like a reference.
1115 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1116 }
1117
Douglas Gregore9d95f12015-07-07 03:57:35 +00001118 // Objective-C type parameters.
1119 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1120 return true;
1121
Guy Benyei11169dd2012-12-18 14:30:41 +00001122 // Issue callbacks for super class.
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128
Douglas Gregore9d95f12015-07-07 03:57:35 +00001129 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1130 if (Visit(SuperClassTInfo->getTypeLoc()))
1131 return true;
1132
Guy Benyei11169dd2012-12-18 14:30:41 +00001133 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1134 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1135 E = D->protocol_end(); I != E; ++I, ++PL)
1136 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1137 return true;
1138
1139 return VisitObjCContainerDecl(D);
1140}
1141
1142bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1143 return VisitObjCContainerDecl(D);
1144}
1145
1146bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1147 // 'ID' could be null when dealing with invalid code.
1148 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1149 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1150 return true;
1151
1152 return VisitObjCImplDecl(D);
1153}
1154
1155bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1156#if 0
1157 // Issue callbacks for super class.
1158 // FIXME: No source location information!
1159 if (D->getSuperClass() &&
1160 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1161 D->getSuperClassLoc(),
1162 TU)))
1163 return true;
1164#endif
1165
1166 return VisitObjCImplDecl(D);
1167}
1168
1169bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1170 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1171 if (PD->isIvarNameSpecified())
1172 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1173
1174 return false;
1175}
1176
1177bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1178 return VisitDeclContext(D);
1179}
1180
1181bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1188 D->getTargetNameLoc(), TU));
1189}
1190
1191bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1192 // Visit nested-name-specifier.
1193 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1194 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1195 return true;
1196 }
1197
1198 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1199 return true;
1200
1201 return VisitDeclarationNameInfo(D->getNameInfo());
1202}
1203
1204bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1205 // Visit nested-name-specifier.
1206 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1207 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1208 return true;
1209
1210 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1211 D->getIdentLocation(), TU));
1212}
1213
1214bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1215 // Visit nested-name-specifier.
1216 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1218 return true;
1219 }
1220
1221 return VisitDeclarationNameInfo(D->getNameInfo());
1222}
1223
1224bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1225 UnresolvedUsingTypenameDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
1230
1231 return false;
1232}
1233
1234bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1235 switch (Name.getName().getNameKind()) {
1236 case clang::DeclarationName::Identifier:
1237 case clang::DeclarationName::CXXLiteralOperatorName:
1238 case clang::DeclarationName::CXXOperatorName:
1239 case clang::DeclarationName::CXXUsingDirective:
1240 return false;
1241
1242 case clang::DeclarationName::CXXConstructorName:
1243 case clang::DeclarationName::CXXDestructorName:
1244 case clang::DeclarationName::CXXConversionFunctionName:
1245 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1246 return Visit(TSInfo->getTypeLoc());
1247 return false;
1248
1249 case clang::DeclarationName::ObjCZeroArgSelector:
1250 case clang::DeclarationName::ObjCOneArgSelector:
1251 case clang::DeclarationName::ObjCMultiArgSelector:
1252 // FIXME: Per-identifier location info?
1253 return false;
1254 }
1255
1256 llvm_unreachable("Invalid DeclarationName::Kind!");
1257}
1258
1259bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1260 SourceRange Range) {
1261 // FIXME: This whole routine is a hack to work around the lack of proper
1262 // source information in nested-name-specifiers (PR5791). Since we do have
1263 // a beginning source location, we can visit the first component of the
1264 // nested-name-specifier, if it's a single-token component.
1265 if (!NNS)
1266 return false;
1267
1268 // Get the first component in the nested-name-specifier.
1269 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1270 NNS = Prefix;
1271
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1275 TU));
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Range.getBegin(), TU));
1280
1281 case NestedNameSpecifier::TypeSpec: {
1282 // If the type has a form where we know that the beginning of the source
1283 // range matches up with a reference cursor. Visit the appropriate reference
1284 // cursor.
1285 const Type *T = NNS->getAsType();
1286 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1287 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1288 if (const TagType *Tag = dyn_cast<TagType>(T))
1289 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1290 if (const TemplateSpecializationType *TST
1291 = dyn_cast<TemplateSpecializationType>(T))
1292 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1293 break;
1294 }
1295
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 case NestedNameSpecifier::Global:
1298 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001299 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001300 break;
1301 }
1302
1303 return false;
1304}
1305
1306bool
1307CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1308 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1309 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1310 Qualifiers.push_back(Qualifier);
1311
1312 while (!Qualifiers.empty()) {
1313 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1314 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1315 switch (NNS->getKind()) {
1316 case NestedNameSpecifier::Namespace:
1317 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1318 Q.getLocalBeginLoc(),
1319 TU)))
1320 return true;
1321
1322 break;
1323
1324 case NestedNameSpecifier::NamespaceAlias:
1325 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1326 Q.getLocalBeginLoc(),
1327 TU)))
1328 return true;
1329
1330 break;
1331
1332 case NestedNameSpecifier::TypeSpec:
1333 case NestedNameSpecifier::TypeSpecWithTemplate:
1334 if (Visit(Q.getTypeLoc()))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::Global:
1340 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001341 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001342 break;
1343 }
1344 }
1345
1346 return false;
1347}
1348
1349bool CursorVisitor::VisitTemplateParameters(
1350 const TemplateParameterList *Params) {
1351 if (!Params)
1352 return false;
1353
1354 for (TemplateParameterList::const_iterator P = Params->begin(),
1355 PEnd = Params->end();
1356 P != PEnd; ++P) {
1357 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1364bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1365 switch (Name.getKind()) {
1366 case TemplateName::Template:
1367 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1368
1369 case TemplateName::OverloadedTemplate:
1370 // Visit the overloaded template set.
1371 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1372 return true;
1373
1374 return false;
1375
1376 case TemplateName::DependentTemplate:
1377 // FIXME: Visit nested-name-specifier.
1378 return false;
1379
1380 case TemplateName::QualifiedTemplate:
1381 // FIXME: Visit nested-name-specifier.
1382 return Visit(MakeCursorTemplateRef(
1383 Name.getAsQualifiedTemplateName()->getDecl(),
1384 Loc, TU));
1385
1386 case TemplateName::SubstTemplateTemplateParm:
1387 return Visit(MakeCursorTemplateRef(
1388 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1389 Loc, TU));
1390
1391 case TemplateName::SubstTemplateTemplateParmPack:
1392 return Visit(MakeCursorTemplateRef(
1393 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1394 Loc, TU));
1395 }
1396
1397 llvm_unreachable("Invalid TemplateName::Kind!");
1398}
1399
1400bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1401 switch (TAL.getArgument().getKind()) {
1402 case TemplateArgument::Null:
1403 case TemplateArgument::Integral:
1404 case TemplateArgument::Pack:
1405 return false;
1406
1407 case TemplateArgument::Type:
1408 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1409 return Visit(TSInfo->getTypeLoc());
1410 return false;
1411
1412 case TemplateArgument::Declaration:
1413 if (Expr *E = TAL.getSourceDeclExpression())
1414 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1415 return false;
1416
1417 case TemplateArgument::NullPtr:
1418 if (Expr *E = TAL.getSourceNullPtrExpression())
1419 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1420 return false;
1421
1422 case TemplateArgument::Expression:
1423 if (Expr *E = TAL.getSourceExpression())
1424 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1425 return false;
1426
1427 case TemplateArgument::Template:
1428 case TemplateArgument::TemplateExpansion:
1429 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1430 return true;
1431
1432 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1433 TAL.getTemplateNameLoc());
1434 }
1435
1436 llvm_unreachable("Invalid TemplateArgument::Kind!");
1437}
1438
1439bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1440 return VisitDeclContext(D);
1441}
1442
1443bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1444 return Visit(TL.getUnqualifiedLoc());
1445}
1446
1447bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1448 ASTContext &Context = AU->getASTContext();
1449
1450 // Some builtin types (such as Objective-C's "id", "sel", and
1451 // "Class") have associated declarations. Create cursors for those.
1452 QualType VisitType;
1453 switch (TL.getTypePtr()->getKind()) {
1454
1455 case BuiltinType::Void:
1456 case BuiltinType::NullPtr:
1457 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001458 case BuiltinType::OCLImage1d:
1459 case BuiltinType::OCLImage1dArray:
1460 case BuiltinType::OCLImage1dBuffer:
1461 case BuiltinType::OCLImage2d:
1462 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001463 case BuiltinType::OCLImage2dDepth:
1464 case BuiltinType::OCLImage2dArrayDepth:
1465 case BuiltinType::OCLImage2dMSAA:
1466 case BuiltinType::OCLImage2dArrayMSAA:
1467 case BuiltinType::OCLImage2dMSAADepth:
1468 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001469 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001470 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001471 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001472 case BuiltinType::OCLClkEvent:
1473 case BuiltinType::OCLQueue:
1474 case BuiltinType::OCLNDRange:
1475 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001476#define BUILTIN_TYPE(Id, SingletonId)
1477#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#include "clang/AST/BuiltinTypes.def"
1482 break;
1483
1484 case BuiltinType::ObjCId:
1485 VisitType = Context.getObjCIdType();
1486 break;
1487
1488 case BuiltinType::ObjCClass:
1489 VisitType = Context.getObjCClassType();
1490 break;
1491
1492 case BuiltinType::ObjCSel:
1493 VisitType = Context.getObjCSelType();
1494 break;
1495 }
1496
1497 if (!VisitType.isNull()) {
1498 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1499 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1500 TU));
1501 }
1502
1503 return false;
1504}
1505
1506bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1507 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1508}
1509
1510bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1511 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1512}
1513
1514bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1515 if (TL.isDefinition())
1516 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1517
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1522 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1523}
1524
1525bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1526 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1527 return true;
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1533 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1534 return true;
1535
Douglas Gregore9d95f12015-07-07 03:57:35 +00001536 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1537 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1538 return true;
1539 }
1540
Guy Benyei11169dd2012-12-18 14:30:41 +00001541 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1542 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1543 TU)))
1544 return true;
1545 }
1546
1547 return false;
1548}
1549
1550bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1551 return Visit(TL.getPointeeLoc());
1552}
1553
1554bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1555 return Visit(TL.getInnerLoc());
1556}
1557
1558bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1579 return Visit(TL.getModifiedLoc());
1580}
1581
1582bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1583 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001584 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 return true;
1586
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001587 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1588 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1590 return true;
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1596 if (Visit(TL.getElementLoc()))
1597 return true;
1598
1599 if (Expr *Size = TL.getSizeExpr())
1600 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1601
1602 return false;
1603}
1604
Reid Kleckner8a365022013-06-24 17:51:48 +00001605bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Reid Kleckner0503a872013-12-05 01:23:43 +00001609bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Guy Benyei11169dd2012-12-18 14:30:41 +00001613bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1614 TemplateSpecializationTypeLoc TL) {
1615 // Visit the template name.
1616 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1617 TL.getTemplateNameLoc()))
1618 return true;
1619
1620 // Visit the template arguments.
1621 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1622 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1623 return true;
1624
1625 return false;
1626}
1627
1628bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1629 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1630}
1631
1632bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1633 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1634 return Visit(TSInfo->getTypeLoc());
1635
1636 return false;
1637}
1638
1639bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1640 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1641 return Visit(TSInfo->getTypeLoc());
1642
1643 return false;
1644}
1645
1646bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1647 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1648 return true;
1649
1650 return false;
1651}
1652
1653bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1654 DependentTemplateSpecializationTypeLoc TL) {
1655 // Visit the nested-name-specifier, if there is one.
1656 if (TL.getQualifierLoc() &&
1657 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1658 return true;
1659
1660 // Visit the template arguments.
1661 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1662 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1663 return true;
1664
1665 return false;
1666}
1667
1668bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1669 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1670 return true;
1671
1672 return Visit(TL.getNamedTypeLoc());
1673}
1674
1675bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1676 return Visit(TL.getPatternLoc());
1677}
1678
1679bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1680 if (Expr *E = TL.getUnderlyingExpr())
1681 return Visit(MakeCXCursor(E, StmtParent, TU));
1682
1683 return false;
1684}
1685
1686bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1687 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1688}
1689
1690bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1691 return Visit(TL.getValueLoc());
1692}
1693
1694#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1695bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1696 return Visit##PARENT##Loc(TL); \
1697}
1698
1699DEFAULT_TYPELOC_IMPL(Complex, Type)
1700DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1705DEFAULT_TYPELOC_IMPL(Vector, Type)
1706DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1707DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1708DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(Record, TagType)
1710DEFAULT_TYPELOC_IMPL(Enum, TagType)
1711DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1713DEFAULT_TYPELOC_IMPL(Auto, Type)
1714
1715bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1716 // Visit the nested-name-specifier, if present.
1717 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1718 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1719 return true;
1720
1721 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001722 for (const auto &I : D->bases()) {
1723 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 return true;
1725 }
1726 }
1727
1728 return VisitTagDecl(D);
1729}
1730
1731bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001732 for (const auto *I : D->attrs())
1733 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 return true;
1735
1736 return false;
1737}
1738
1739//===----------------------------------------------------------------------===//
1740// Data-recursive visitor methods.
1741//===----------------------------------------------------------------------===//
1742
1743namespace {
1744#define DEF_JOB(NAME, DATA, KIND)\
1745class NAME : public VisitorJob {\
1746public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 NAME(const DATA *d, CXCursor parent) : \
1748 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001750 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001751};
1752
1753DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1754DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1755DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1756DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1757DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1758 ExplicitTemplateArgsVisitKind)
1759DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1760DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1761DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1762#undef DEF_JOB
1763
1764class DeclVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001767 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001768 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == DeclVisitKind;
1771 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001773 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001774};
1775class TypeLocVisit : public VisitorJob {
1776public:
1777 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1778 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1779 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1780
1781 static bool classof(const VisitorJob *VJ) {
1782 return VJ->getKind() == TypeLocVisitKind;
1783 }
1784
1785 TypeLoc get() const {
1786 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 }
1789};
1790
1791class LabelRefVisit : public VisitorJob {
1792public:
1793 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1794 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1795 labelLoc.getPtrEncoding()) {}
1796
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const LabelDecl *get() const {
1801 return static_cast<const LabelDecl *>(data[0]);
1802 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromPtrEncoding(data[1]); }
1805};
1806
1807class NestedNameSpecifierLocVisit : public VisitorJob {
1808public:
1809 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1810 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1811 Qualifier.getNestedNameSpecifier(),
1812 Qualifier.getOpaqueData()) { }
1813
1814 static bool classof(const VisitorJob *VJ) {
1815 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1816 }
1817
1818 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 return NestedNameSpecifierLoc(
1820 const_cast<NestedNameSpecifier *>(
1821 static_cast<const NestedNameSpecifier *>(data[0])),
1822 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001823 }
1824};
1825
1826class DeclarationNameInfoVisit : public VisitorJob {
1827public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001828 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001829 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001830 static bool classof(const VisitorJob *VJ) {
1831 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1832 }
1833 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001834 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001835 switch (S->getStmtClass()) {
1836 default:
1837 llvm_unreachable("Unhandled Stmt");
1838 case clang::Stmt::MSDependentExistsStmtClass:
1839 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1840 case Stmt::CXXDependentScopeMemberExprClass:
1841 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1842 case Stmt::DependentScopeDeclRefExprClass:
1843 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001844 case Stmt::OMPCriticalDirectiveClass:
1845 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 }
1847 }
1848};
1849class MemberRefVisit : public VisitorJob {
1850public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001852 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1853 L.getPtrEncoding()) {}
1854 static bool classof(const VisitorJob *VJ) {
1855 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1856 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 const FieldDecl *get() const {
1858 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 }
1860 SourceLocation getLoc() const {
1861 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1862 }
1863};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 VisitorWorkList &WL;
1867 CXCursor Parent;
1868public:
1869 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1870 : WL(wl), Parent(parent) {}
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1873 void VisitBlockExpr(const BlockExpr *B);
1874 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1875 void VisitCompoundStmt(const CompoundStmt *S);
1876 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1877 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1878 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1879 void VisitCXXNewExpr(const CXXNewExpr *E);
1880 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1881 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1882 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1883 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1884 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1885 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1886 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1887 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001888 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void VisitDeclRefExpr(const DeclRefExpr *D);
1890 void VisitDeclStmt(const DeclStmt *S);
1891 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1892 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1893 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1894 void VisitForStmt(const ForStmt *FS);
1895 void VisitGotoStmt(const GotoStmt *GS);
1896 void VisitIfStmt(const IfStmt *If);
1897 void VisitInitListExpr(const InitListExpr *IE);
1898 void VisitMemberExpr(const MemberExpr *M);
1899 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1900 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1901 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1902 void VisitOverloadExpr(const OverloadExpr *E);
1903 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1904 void VisitStmt(const Stmt *S);
1905 void VisitSwitchStmt(const SwitchStmt *S);
1906 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1908 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1909 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1910 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1911 void VisitVAArgExpr(const VAArgExpr *E);
1912 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1913 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1914 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1915 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001917 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001919 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001920 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001921 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001922 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001923 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001924 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001925 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001926 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001927 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001928 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001929 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001930 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001931 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001932 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001933 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001934 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001935 void
1936 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001937 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001938 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001939 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001940 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001941 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001942 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001943 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001944
Guy Benyei11169dd2012-12-18 14:30:41 +00001945private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001946 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1948 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001949 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1950 void AddStmt(const Stmt *S);
1951 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001952 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001953 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001955};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001956} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001957
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 // 'S' should always be non-null, since it comes from the
1960 // statement we are visiting.
1961 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1962}
1963
1964void
1965EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1966 if (Qualifier)
1967 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1968}
1969
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001970void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 if (S)
1972 WL.push_back(StmtVisit(S, Parent));
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 if (D)
1976 WL.push_back(DeclVisit(D, Parent, isFirst));
1977}
1978void EnqueueVisitor::
1979 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1980 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001982}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 if (D)
1985 WL.push_back(MemberRefVisit(D, L, Parent));
1986}
1987void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1988 if (TI)
1989 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1990 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001993 for (const Stmt *SubStmt : S->children()) {
1994 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 }
1996 if (size == WL.size())
1997 return;
1998 // Now reverse the entries we just added. This will match the DFS
1999 // ordering performed by the worklist.
2000 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2001 std::reverse(I, E);
2002}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003namespace {
2004class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2005 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002006 /// \brief Process clauses with list of variables.
2007 template <typename T>
2008 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002009public:
2010 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2011#define OPENMP_CLAUSE(Name, Class) \
2012 void Visit##Class(const Class *C);
2013#include "clang/Basic/OpenMPKinds.def"
2014};
2015
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002016void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2017 Visitor->AddStmt(C->getCondition());
2018}
2019
Alexey Bataev3778b602014-07-17 07:32:53 +00002020void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2021 Visitor->AddStmt(C->getCondition());
2022}
2023
Alexey Bataev568a8332014-03-06 06:15:19 +00002024void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2025 Visitor->AddStmt(C->getNumThreads());
2026}
2027
Alexey Bataev62c87d22014-03-21 04:51:18 +00002028void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2029 Visitor->AddStmt(C->getSafelen());
2030}
2031
Alexey Bataev66b15b52015-08-21 11:14:16 +00002032void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2033 Visitor->AddStmt(C->getSimdlen());
2034}
2035
Alexander Musman8bd31e62014-05-27 15:12:19 +00002036void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2037 Visitor->AddStmt(C->getNumForLoops());
2038}
2039
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002040void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002041
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002042void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2043
Alexey Bataev56dafe82014-06-20 07:16:17 +00002044void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2045 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002046 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002047}
2048
Alexey Bataev10e775f2015-07-30 11:36:16 +00002049void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2050 Visitor->AddStmt(C->getNumForLoops());
2051}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002052
Alexey Bataev236070f2014-06-20 11:19:47 +00002053void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2054
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002055void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2056
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002057void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2058
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002059void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2060
Alexey Bataevdea47612014-07-23 07:46:59 +00002061void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2062
Alexey Bataev67a4f222014-07-23 10:25:33 +00002063void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2064
Alexey Bataev459dec02014-07-24 06:46:57 +00002065void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2066
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002067void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2068
Alexey Bataev346265e2015-09-25 10:37:12 +00002069void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2070
Michael Wonge710d542015-08-07 16:16:36 +00002071void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2072 Visitor->AddStmt(C->getDevice());
2073}
2074
Alexey Bataev756c1962013-09-24 03:17:45 +00002075template<typename T>
2076void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002077 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002078 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002079 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002080}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002081
2082void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002083 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002084 for (const auto *E : C->private_copies()) {
2085 Visitor->AddStmt(E);
2086 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002087}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002088void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2089 const OMPFirstprivateClause *C) {
2090 VisitOMPClauseList(C);
2091}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002092void OMPClauseEnqueue::VisitOMPLastprivateClause(
2093 const OMPLastprivateClause *C) {
2094 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002095 for (auto *E : C->private_copies()) {
2096 Visitor->AddStmt(E);
2097 }
2098 for (auto *E : C->source_exprs()) {
2099 Visitor->AddStmt(E);
2100 }
2101 for (auto *E : C->destination_exprs()) {
2102 Visitor->AddStmt(E);
2103 }
2104 for (auto *E : C->assignment_ops()) {
2105 Visitor->AddStmt(E);
2106 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002107}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002108void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002109 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002110}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002111void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2112 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002113 for (auto *E : C->lhs_exprs()) {
2114 Visitor->AddStmt(E);
2115 }
2116 for (auto *E : C->rhs_exprs()) {
2117 Visitor->AddStmt(E);
2118 }
2119 for (auto *E : C->reduction_ops()) {
2120 Visitor->AddStmt(E);
2121 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002122}
Alexander Musman8dba6642014-04-22 13:09:42 +00002123void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2124 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002125 for (const auto *E : C->privates()) {
2126 Visitor->AddStmt(E);
2127 }
Alexander Musman3276a272015-03-21 10:12:56 +00002128 for (const auto *E : C->inits()) {
2129 Visitor->AddStmt(E);
2130 }
2131 for (const auto *E : C->updates()) {
2132 Visitor->AddStmt(E);
2133 }
2134 for (const auto *E : C->finals()) {
2135 Visitor->AddStmt(E);
2136 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002137 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002138 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002139}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002140void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2141 VisitOMPClauseList(C);
2142 Visitor->AddStmt(C->getAlignment());
2143}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002144void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2145 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002146 for (auto *E : C->source_exprs()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (auto *E : C->destination_exprs()) {
2150 Visitor->AddStmt(E);
2151 }
2152 for (auto *E : C->assignment_ops()) {
2153 Visitor->AddStmt(E);
2154 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002155}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002156void
2157OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2158 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002159 for (auto *E : C->source_exprs()) {
2160 Visitor->AddStmt(E);
2161 }
2162 for (auto *E : C->destination_exprs()) {
2163 Visitor->AddStmt(E);
2164 }
2165 for (auto *E : C->assignment_ops()) {
2166 Visitor->AddStmt(E);
2167 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002168}
Alexey Bataev6125da92014-07-21 11:26:11 +00002169void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2170 VisitOMPClauseList(C);
2171}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002172void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2173 VisitOMPClauseList(C);
2174}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002175}
Alexey Bataev756c1962013-09-24 03:17:45 +00002176
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002177void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2178 unsigned size = WL.size();
2179 OMPClauseEnqueue Visitor(this);
2180 Visitor.Visit(S);
2181 if (size == WL.size())
2182 return;
2183 // Now reverse the entries we just added. This will match the DFS
2184 // ordering performed by the worklist.
2185 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2186 std::reverse(I, E);
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddDecl(B->getBlockDecl());
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 EnqueueChildren(E);
2196 AddTypeLoc(E->getTypeSourceInfo());
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002199 for (auto &I : llvm::reverse(S->body()))
2200 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002201}
2202void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 AddStmt(S->getSubStmt());
2205 AddDeclarationNameInfo(S);
2206 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2207 AddNestedNameSpecifierLoc(QualifierLoc);
2208}
2209
2210void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2213 AddDeclarationNameInfo(E);
2214 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2215 AddNestedNameSpecifierLoc(QualifierLoc);
2216 if (!E->isImplicitAccess())
2217 AddStmt(E->getBase());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 // Enqueue the initializer , if any.
2221 AddStmt(E->getInitializer());
2222 // Enqueue the array size, if any.
2223 AddStmt(E->getArraySize());
2224 // Enqueue the allocated type.
2225 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2226 // Enqueue the placement arguments.
2227 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2228 AddStmt(E->getPlacementArg(I-1));
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2232 AddStmt(CE->getArg(I-1));
2233 AddStmt(CE->getCallee());
2234 AddStmt(CE->getArg(0));
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2237 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 // Visit the name of the type being destroyed.
2239 AddTypeLoc(E->getDestroyedTypeInfo());
2240 // Visit the scope type that looks disturbingly like the nested-name-specifier
2241 // but isn't.
2242 AddTypeLoc(E->getScopeTypeInfo());
2243 // Visit the nested-name-specifier.
2244 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2245 AddNestedNameSpecifierLoc(QualifierLoc);
2246 // Visit base expression.
2247 AddStmt(E->getBase());
2248}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2250 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddTypeLoc(E->getTypeSourceInfo());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2254 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 EnqueueChildren(E);
2256 AddTypeLoc(E->getTypeSourceInfo());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 EnqueueChildren(E);
2260 if (E->isTypeOperand())
2261 AddTypeLoc(E->getTypeOperandSourceInfo());
2262}
2263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2265 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(E);
2267 AddTypeLoc(E->getTypeSourceInfo());
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 EnqueueChildren(E);
2271 if (E->isTypeOperand())
2272 AddTypeLoc(E->getTypeOperandSourceInfo());
2273}
2274
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(S);
2277 AddDecl(S->getExceptionDecl());
2278}
2279
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002280void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002281 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002282 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002283 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002284}
2285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 if (DR->hasExplicitTemplateArgs()) {
2288 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2289 }
2290 WL.push_back(DeclRefExprParts(DR, Parent));
2291}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2293 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2295 AddDeclarationNameInfo(E);
2296 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 unsigned size = WL.size();
2300 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002301 for (const auto *D : S->decls()) {
2302 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 isFirst = false;
2304 }
2305 if (size == WL.size())
2306 return;
2307 // Now reverse the entries we just added. This will match the DFS
2308 // ordering performed by the worklist.
2309 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2310 std::reverse(I, E);
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 D = E->designators_rbegin(), DEnd = E->designators_rend();
2316 D != DEnd; ++D) {
2317 if (D->isFieldDesignator()) {
2318 if (FieldDecl *Field = D->getField())
2319 AddMemberRef(Field, D->getFieldLoc());
2320 continue;
2321 }
2322 if (D->isArrayDesignator()) {
2323 AddStmt(E->getArrayIndex(*D));
2324 continue;
2325 }
2326 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2327 AddStmt(E->getArrayRangeEnd(*D));
2328 AddStmt(E->getArrayRangeStart(*D));
2329 }
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 EnqueueChildren(E);
2333 AddTypeLoc(E->getTypeInfoAsWritten());
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 AddStmt(FS->getBody());
2337 AddStmt(FS->getInc());
2338 AddStmt(FS->getCond());
2339 AddDecl(FS->getConditionVariable());
2340 AddStmt(FS->getInit());
2341}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2344}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 AddStmt(If->getElse());
2347 AddStmt(If->getThen());
2348 AddStmt(If->getCond());
2349 AddDecl(If->getConditionVariable());
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 // We care about the syntactic form of the initializer list, only.
2353 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2354 IE = Syntactic;
2355 EnqueueChildren(IE);
2356}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 WL.push_back(MemberExprParts(M, Parent));
2359
2360 // If the base of the member access expression is an implicit 'this', don't
2361 // visit it.
2362 // FIXME: If we ever want to show these implicit accesses, this will be
2363 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002364 if (M->isImplicitAccess())
2365 return;
2366
2367 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2368 // real field that that we are interested in.
2369 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2370 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2371 if (FD->isAnonymousStructOrUnion()) {
2372 AddStmt(SubME->getBase());
2373 return;
2374 }
2375 }
2376 }
2377
2378 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 AddTypeLoc(E->getEncodedTypeSourceInfo());
2382}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 EnqueueChildren(M);
2385 AddTypeLoc(M->getClassReceiverTypeInfo());
2386}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 // Visit the components of the offsetof expression.
2389 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2390 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2391 const OffsetOfNode &Node = E->getComponent(I-1);
2392 switch (Node.getKind()) {
2393 case OffsetOfNode::Array:
2394 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2395 break;
2396 case OffsetOfNode::Field:
2397 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2398 break;
2399 case OffsetOfNode::Identifier:
2400 case OffsetOfNode::Base:
2401 continue;
2402 }
2403 }
2404 // Visit the type into which we're computing the offset.
2405 AddTypeLoc(E->getTypeSourceInfo());
2406}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2409 WL.push_back(OverloadExprParts(E, Parent));
2410}
2411void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 EnqueueChildren(E);
2414 if (E->isArgumentType())
2415 AddTypeLoc(E->getArgumentTypeInfo());
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 EnqueueChildren(S);
2419}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 AddStmt(S->getBody());
2422 AddStmt(S->getCond());
2423 AddDecl(S->getConditionVariable());
2424}
2425
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 AddStmt(W->getBody());
2428 AddStmt(W->getCond());
2429 AddDecl(W->getConditionVariable());
2430}
2431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 for (unsigned I = E->getNumArgs(); I > 0; --I)
2434 AddTypeLoc(E->getArg(I-1));
2435}
2436
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 AddTypeLoc(E->getQueriedTypeSourceInfo());
2439}
2440
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 EnqueueChildren(E);
2443}
2444
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 VisitOverloadExpr(U);
2447 if (!U->isImplicitAccess())
2448 AddStmt(U->getBase());
2449}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 AddStmt(E->getSubExpr());
2452 AddTypeLoc(E->getWrittenTypeInfo());
2453}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002454void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 WL.push_back(SizeOfPackExprParts(E, Parent));
2456}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002457void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 // If the opaque value has a source expression, just transparently
2459 // visit that. This is useful for (e.g.) pseudo-object expressions.
2460 if (Expr *SourceExpr = E->getSourceExpr())
2461 return Visit(SourceExpr);
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 AddStmt(E->getBody());
2465 WL.push_back(LambdaExprParts(E, Parent));
2466}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 // Treat the expression like its syntactic form.
2469 Visit(E->getSyntacticForm());
2470}
2471
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002472void EnqueueVisitor::VisitOMPExecutableDirective(
2473 const OMPExecutableDirective *D) {
2474 EnqueueChildren(D);
2475 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2476 E = D->clauses().end();
2477 I != E; ++I)
2478 EnqueueChildren(*I);
2479}
2480
Alexander Musman3aaab662014-08-19 11:27:13 +00002481void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2482 VisitOMPExecutableDirective(D);
2483}
2484
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002485void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2486 VisitOMPExecutableDirective(D);
2487}
2488
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002489void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002490 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002491}
2492
Alexey Bataevf29276e2014-06-18 04:14:57 +00002493void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002494 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002495}
2496
Alexander Musmanf82886e2014-09-18 05:12:34 +00002497void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2498 VisitOMPLoopDirective(D);
2499}
2500
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002501void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503}
2504
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002505void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2506 VisitOMPExecutableDirective(D);
2507}
2508
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002509void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2510 VisitOMPExecutableDirective(D);
2511}
2512
Alexander Musman80c22892014-07-17 08:54:58 +00002513void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2514 VisitOMPExecutableDirective(D);
2515}
2516
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002517void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2518 VisitOMPExecutableDirective(D);
2519 AddDeclarationNameInfo(D);
2520}
2521
Alexey Bataev4acb8592014-07-07 13:01:15 +00002522void
2523EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002524 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002525}
2526
Alexander Musmane4e893b2014-09-23 09:33:00 +00002527void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2528 const OMPParallelForSimdDirective *D) {
2529 VisitOMPLoopDirective(D);
2530}
2531
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002532void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2533 const OMPParallelSectionsDirective *D) {
2534 VisitOMPExecutableDirective(D);
2535}
2536
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002537void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2538 VisitOMPExecutableDirective(D);
2539}
2540
Alexey Bataev68446b72014-07-18 07:47:19 +00002541void
2542EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002546void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev2df347a2014-07-18 10:17:07 +00002550void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552}
2553
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002554void EnqueueVisitor::VisitOMPTaskgroupDirective(
2555 const OMPTaskgroupDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev6125da92014-07-21 11:26:11 +00002559void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002563void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev0162e452014-07-22 10:10:35 +00002567void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002571void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2572 VisitOMPExecutableDirective(D);
2573}
2574
Michael Wong65f367f2015-07-21 13:44:28 +00002575void EnqueueVisitor::VisitOMPTargetDataDirective(const
2576 OMPTargetDataDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev13314bf2014-10-09 04:18:56 +00002580void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002584void EnqueueVisitor::VisitOMPCancellationPointDirective(
2585 const OMPCancellationPointDirective *D) {
2586 VisitOMPExecutableDirective(D);
2587}
2588
Alexey Bataev80909872015-07-02 11:25:17 +00002589void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2595}
2596
2597bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2598 if (RegionOfInterest.isValid()) {
2599 SourceRange Range = getRawCursorExtent(C);
2600 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2601 return false;
2602 }
2603 return true;
2604}
2605
2606bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2607 while (!WL.empty()) {
2608 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002609 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002610
2611 // Set the Parent field, then back to its old value once we're done.
2612 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2613
2614 switch (LI.getKind()) {
2615 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002616 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002617 if (!D)
2618 continue;
2619
2620 // For now, perform default visitation for Decls.
2621 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2622 cast<DeclVisit>(&LI)->isFirst())))
2623 return true;
2624
2625 continue;
2626 }
2627 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2628 const ASTTemplateArgumentListInfo *ArgList =
2629 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2630 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2631 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2632 Arg != ArgEnd; ++Arg) {
2633 if (VisitTemplateArgumentLoc(*Arg))
2634 return true;
2635 }
2636 continue;
2637 }
2638 case VisitorJob::TypeLocVisitKind: {
2639 // Perform default visitation for TypeLocs.
2640 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2641 return true;
2642 continue;
2643 }
2644 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002645 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 if (LabelStmt *stmt = LS->getStmt()) {
2647 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2648 TU))) {
2649 return true;
2650 }
2651 }
2652 continue;
2653 }
2654
2655 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2656 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2657 if (VisitNestedNameSpecifierLoc(V->get()))
2658 return true;
2659 continue;
2660 }
2661
2662 case VisitorJob::DeclarationNameInfoVisitKind: {
2663 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2664 ->get()))
2665 return true;
2666 continue;
2667 }
2668 case VisitorJob::MemberRefVisitKind: {
2669 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2670 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2671 return true;
2672 continue;
2673 }
2674 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002675 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 if (!S)
2677 continue;
2678
2679 // Update the current cursor.
2680 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2681 if (!IsInRegionOfInterest(Cursor))
2682 continue;
2683 switch (Visitor(Cursor, Parent, ClientData)) {
2684 case CXChildVisit_Break: return true;
2685 case CXChildVisit_Continue: break;
2686 case CXChildVisit_Recurse:
2687 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002688 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 EnqueueWorkList(WL, S);
2690 break;
2691 }
2692 continue;
2693 }
2694 case VisitorJob::MemberExprPartsKind: {
2695 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002696 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002697
2698 // Visit the nested-name-specifier
2699 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2700 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2701 return true;
2702
2703 // Visit the declaration name.
2704 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2705 return true;
2706
2707 // Visit the explicitly-specified template arguments, if any.
2708 if (M->hasExplicitTemplateArgs()) {
2709 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2710 *ArgEnd = Arg + M->getNumTemplateArgs();
2711 Arg != ArgEnd; ++Arg) {
2712 if (VisitTemplateArgumentLoc(*Arg))
2713 return true;
2714 }
2715 }
2716 continue;
2717 }
2718 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002719 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002720 // Visit nested-name-specifier, if present.
2721 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2722 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2723 return true;
2724 // Visit declaration name.
2725 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2726 return true;
2727 continue;
2728 }
2729 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002730 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002731 // Visit the nested-name-specifier.
2732 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2733 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2734 return true;
2735 // Visit the declaration name.
2736 if (VisitDeclarationNameInfo(O->getNameInfo()))
2737 return true;
2738 // Visit the overloaded declaration reference.
2739 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2740 return true;
2741 continue;
2742 }
2743 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002744 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002745 NamedDecl *Pack = E->getPack();
2746 if (isa<TemplateTypeParmDecl>(Pack)) {
2747 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2748 E->getPackLoc(), TU)))
2749 return true;
2750
2751 continue;
2752 }
2753
2754 if (isa<TemplateTemplateParmDecl>(Pack)) {
2755 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2756 E->getPackLoc(), TU)))
2757 return true;
2758
2759 continue;
2760 }
2761
2762 // Non-type template parameter packs and function parameter packs are
2763 // treated like DeclRefExpr cursors.
2764 continue;
2765 }
2766
2767 case VisitorJob::LambdaExprPartsKind: {
2768 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002769 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2771 CEnd = E->explicit_capture_end();
2772 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002773 // FIXME: Lambda init-captures.
2774 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002775 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002776
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2778 C->getLocation(),
2779 TU)))
2780 return true;
2781 }
2782
2783 // Visit parameters and return type, if present.
2784 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2785 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2786 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2787 // Visit the whole type.
2788 if (Visit(TL))
2789 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002790 } else if (FunctionProtoTypeLoc Proto =
2791 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 if (E->hasExplicitParameters()) {
2793 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002794 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2795 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 return true;
2797 } else {
2798 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002799 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002800 return true;
2801 }
2802 }
2803 }
2804 break;
2805 }
2806
2807 case VisitorJob::PostChildrenVisitKind:
2808 if (PostChildrenVisitor(Parent, ClientData))
2809 return true;
2810 break;
2811 }
2812 }
2813 return false;
2814}
2815
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002816bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002817 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 if (!WorkListFreeList.empty()) {
2819 WL = WorkListFreeList.back();
2820 WL->clear();
2821 WorkListFreeList.pop_back();
2822 }
2823 else {
2824 WL = new VisitorWorkList();
2825 WorkListCache.push_back(WL);
2826 }
2827 EnqueueWorkList(*WL, S);
2828 bool result = RunVisitorWorkList(*WL);
2829 WorkListFreeList.push_back(WL);
2830 return result;
2831}
2832
2833namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002834typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002835RefNamePieces
2836buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2837 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2838 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2840 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2841 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2842
2843 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2844
2845 RefNamePieces Pieces;
2846
2847 if (WantQualifier && QLoc.isValid())
2848 Pieces.push_back(QLoc);
2849
2850 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2851 Pieces.push_back(NI.getLoc());
2852
2853 if (WantTemplateArgs && TemplateArgs)
2854 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2855 TemplateArgs->RAngleLoc));
2856
2857 if (Kind == DeclarationName::CXXOperatorName) {
2858 Pieces.push_back(SourceLocation::getFromRawEncoding(
2859 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2860 Pieces.push_back(SourceLocation::getFromRawEncoding(
2861 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2862 }
2863
2864 if (WantSinglePiece) {
2865 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2866 Pieces.clear();
2867 Pieces.push_back(R);
2868 }
2869
2870 return Pieces;
2871}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002872}
Guy Benyei11169dd2012-12-18 14:30:41 +00002873
2874//===----------------------------------------------------------------------===//
2875// Misc. API hooks.
2876//===----------------------------------------------------------------------===//
2877
Chad Rosier05c71aa2013-03-27 18:28:23 +00002878static void fatal_error_handler(void *user_data, const std::string& reason,
2879 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 // Write the result out to stderr avoiding errs() because raw_ostreams can
2881 // call report_fatal_error.
2882 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2883 ::abort();
2884}
2885
Chandler Carruth66660742014-06-27 16:37:27 +00002886namespace {
2887struct RegisterFatalErrorHandler {
2888 RegisterFatalErrorHandler() {
2889 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2890 }
2891};
2892}
2893
2894static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2895
Guy Benyei11169dd2012-12-18 14:30:41 +00002896extern "C" {
2897CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2898 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 // We use crash recovery to make some of our APIs more reliable, implicitly
2900 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002901 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2902 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002903
Chandler Carruth66660742014-06-27 16:37:27 +00002904 // Look through the managed static to trigger construction of the managed
2905 // static which registers our fatal error handler. This ensures it is only
2906 // registered once.
2907 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002908
Adrian Prantlbc068582015-07-08 01:00:30 +00002909 // Initialize targets for clang module support.
2910 llvm::InitializeAllTargets();
2911 llvm::InitializeAllTargetMCs();
2912 llvm::InitializeAllAsmPrinters();
2913 llvm::InitializeAllAsmParsers();
2914
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002915 CIndexer *CIdxr = new CIndexer();
2916
Guy Benyei11169dd2012-12-18 14:30:41 +00002917 if (excludeDeclarationsFromPCH)
2918 CIdxr->setOnlyLocalDecls();
2919 if (displayDiagnostics)
2920 CIdxr->setDisplayDiagnostics();
2921
2922 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2923 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2924 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2925 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2926 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2927 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2928
2929 return CIdxr;
2930}
2931
2932void clang_disposeIndex(CXIndex CIdx) {
2933 if (CIdx)
2934 delete static_cast<CIndexer *>(CIdx);
2935}
2936
2937void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2938 if (CIdx)
2939 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2940}
2941
2942unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2943 if (CIdx)
2944 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2945 return 0;
2946}
2947
2948void clang_toggleCrashRecovery(unsigned isEnabled) {
2949 if (isEnabled)
2950 llvm::CrashRecoveryContext::Enable();
2951 else
2952 llvm::CrashRecoveryContext::Disable();
2953}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002954
Guy Benyei11169dd2012-12-18 14:30:41 +00002955CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2956 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002957 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002958 enum CXErrorCode Result =
2959 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002960 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002961 assert((TU && Result == CXError_Success) ||
2962 (!TU && Result != CXError_Success));
2963 return TU;
2964}
2965
2966enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2967 const char *ast_filename,
2968 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002969 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002970 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002971
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002972 if (!CIdx || !ast_filename || !out_TU)
2973 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002974
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002975 LOG_FUNC_SECTION {
2976 *Log << ast_filename;
2977 }
2978
Guy Benyei11169dd2012-12-18 14:30:41 +00002979 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2980 FileSystemOptions FileSystemOpts;
2981
Justin Bognerd512c1e2014-10-15 00:33:06 +00002982 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2983 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002984 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002985 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002986 FileSystemOpts, /*UseDebugInfo=*/false,
2987 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002988 /*CaptureDiagnostics=*/true,
2989 /*AllowPCHWithCompilerErrors=*/true,
2990 /*UserFilesAreVolatile=*/true);
2991 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002993}
2994
2995unsigned clang_defaultEditingTranslationUnitOptions() {
2996 return CXTranslationUnit_PrecompiledPreamble |
2997 CXTranslationUnit_CacheCompletionResults;
2998}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999
Guy Benyei11169dd2012-12-18 14:30:41 +00003000CXTranslationUnit
3001clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3002 const char *source_filename,
3003 int num_command_line_args,
3004 const char * const *command_line_args,
3005 unsigned num_unsaved_files,
3006 struct CXUnsavedFile *unsaved_files) {
3007 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3008 return clang_parseTranslationUnit(CIdx, source_filename,
3009 command_line_args, num_command_line_args,
3010 unsaved_files, num_unsaved_files,
3011 Options);
3012}
3013
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003014static CXErrorCode
3015clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3016 const char *const *command_line_args,
3017 int num_command_line_args,
3018 ArrayRef<CXUnsavedFile> unsaved_files,
3019 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003020 // Set up the initial return values.
3021 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003022 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003023
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003024 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003025 if (!CIdx || !out_TU)
3026 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3029
3030 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3031 setThreadBackgroundPriority();
3032
3033 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3034 // FIXME: Add a flag for modules.
3035 TranslationUnitKind TUKind
3036 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003037 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 = options & CXTranslationUnit_CacheCompletionResults;
3039 bool IncludeBriefCommentsInCodeCompletion
3040 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3041 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3042 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3043
3044 // Configure the diagnostics.
3045 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003046 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003047
3048 // Recover resources if we crash before exiting this function.
3049 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3050 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003051 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003052
Ahmed Charlesb8984322014-03-07 20:03:18 +00003053 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3054 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003055
3056 // Recover resources if we crash before exiting this function.
3057 llvm::CrashRecoveryContextCleanupRegistrar<
3058 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3059
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003060 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003061 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003062 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003063 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003064 }
3065
Ahmed Charlesb8984322014-03-07 20:03:18 +00003066 std::unique_ptr<std::vector<const char *>> Args(
3067 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003068
3069 // Recover resources if we crash before exiting this method.
3070 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3071 ArgsCleanup(Args.get());
3072
3073 // Since the Clang C library is primarily used by batch tools dealing with
3074 // (often very broken) source code, where spell-checking can have a
3075 // significant negative impact on performance (particularly when
3076 // precompiled headers are involved), we disable it by default.
3077 // Only do this if we haven't found a spell-checking-related argument.
3078 bool FoundSpellCheckingArgument = false;
3079 for (int I = 0; I != num_command_line_args; ++I) {
3080 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3081 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3082 FoundSpellCheckingArgument = true;
3083 break;
3084 }
3085 }
3086 if (!FoundSpellCheckingArgument)
3087 Args->push_back("-fno-spell-checking");
3088
3089 Args->insert(Args->end(), command_line_args,
3090 command_line_args + num_command_line_args);
3091
3092 // The 'source_filename' argument is optional. If the caller does not
3093 // specify it then it is assumed that the source file is specified
3094 // in the actual argument list.
3095 // Put the source file after command_line_args otherwise if '-x' flag is
3096 // present it will be unused.
3097 if (source_filename)
3098 Args->push_back(source_filename);
3099
3100 // Do we need the detailed preprocessing record?
3101 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3102 Args->push_back("-Xclang");
3103 Args->push_back("-detailed-preprocessing-record");
3104 }
3105
3106 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003107 std::unique_ptr<ASTUnit> ErrUnit;
3108 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003109 Args->data(), Args->data() + Args->size(),
3110 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003111 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3112 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3113 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3114 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3115 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3116 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003117
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003118 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003119 if (!Unit && !ErrUnit)
3120 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003121
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 if (NumErrors != Diags->getClient()->getNumErrors()) {
3123 // Make sure to check that 'Unit' is non-NULL.
3124 if (CXXIdx->getDisplayDiagnostics())
3125 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3126 }
3127
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003128 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3129 return CXError_ASTReadError;
3130
3131 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3132 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003133}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134
3135CXTranslationUnit
3136clang_parseTranslationUnit(CXIndex CIdx,
3137 const char *source_filename,
3138 const char *const *command_line_args,
3139 int num_command_line_args,
3140 struct CXUnsavedFile *unsaved_files,
3141 unsigned num_unsaved_files,
3142 unsigned options) {
3143 CXTranslationUnit TU;
3144 enum CXErrorCode Result = clang_parseTranslationUnit2(
3145 CIdx, source_filename, command_line_args, num_command_line_args,
3146 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003147 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003148 assert((TU && Result == CXError_Success) ||
3149 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150 return TU;
3151}
3152
3153enum CXErrorCode clang_parseTranslationUnit2(
3154 CXIndex CIdx,
3155 const char *source_filename,
3156 const char *const *command_line_args,
3157 int num_command_line_args,
3158 struct CXUnsavedFile *unsaved_files,
3159 unsigned num_unsaved_files,
3160 unsigned options,
3161 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003162 LOG_FUNC_SECTION {
3163 *Log << source_filename << ": ";
3164 for (int i = 0; i != num_command_line_args; ++i)
3165 *Log << command_line_args[i] << " ";
3166 }
3167
Alp Toker9d85b182014-07-07 01:23:14 +00003168 if (num_unsaved_files && !unsaved_files)
3169 return CXError_InvalidArguments;
3170
Alp Toker5c532982014-07-07 22:42:03 +00003171 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003172 auto ParseTranslationUnitImpl = [=, &result] {
3173 result = clang_parseTranslationUnit_Impl(
3174 CIdx, source_filename, command_line_args, num_command_line_args,
3175 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3176 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 llvm::CrashRecoveryContext CRC;
3178
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003179 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3181 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3182 fprintf(stderr, " 'command_line_args' : [");
3183 for (int i = 0; i != num_command_line_args; ++i) {
3184 if (i)
3185 fprintf(stderr, ", ");
3186 fprintf(stderr, "'%s'", command_line_args[i]);
3187 }
3188 fprintf(stderr, "],\n");
3189 fprintf(stderr, " 'unsaved_files' : [");
3190 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3191 if (i)
3192 fprintf(stderr, ", ");
3193 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3194 unsaved_files[i].Length);
3195 }
3196 fprintf(stderr, "],\n");
3197 fprintf(stderr, " 'options' : %d,\n", options);
3198 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003199
3200 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003202 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003203 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 }
Alp Toker5c532982014-07-07 22:42:03 +00003205
3206 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003207}
3208
3209unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3210 return CXSaveTranslationUnit_None;
3211}
3212
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003213static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3214 const char *FileName,
3215 unsigned options) {
3216 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3218 setThreadBackgroundPriority();
3219
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003220 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3221 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003222}
3223
3224int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3225 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003226 LOG_FUNC_SECTION {
3227 *Log << TU << ' ' << FileName;
3228 }
3229
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003230 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003231 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003233 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003234
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003235 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3237 if (!CXXUnit->hasSema())
3238 return CXSaveError_InvalidTU;
3239
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003240 CXSaveError result;
3241 auto SaveTranslationUnitImpl = [=, &result]() {
3242 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3243 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003244
3245 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3246 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003247 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003248
3249 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3250 PrintLibclangResourceUsage(TU);
3251
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003252 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 }
3254
3255 // We have an AST that has invalid nodes due to compiler errors.
3256 // Use a crash recovery thread for protection.
3257
3258 llvm::CrashRecoveryContext CRC;
3259
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003260 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3262 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3263 fprintf(stderr, " 'options' : %d,\n", options);
3264 fprintf(stderr, "}\n");
3265
3266 return CXSaveError_Unknown;
3267
3268 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3269 PrintLibclangResourceUsage(TU);
3270 }
3271
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003272 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003273}
3274
3275void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3276 if (CTUnit) {
3277 // If the translation unit has been marked as unsafe to free, just discard
3278 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003279 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3280 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 return;
3282
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003283 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003284 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3286 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003287 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 delete CTUnit;
3289 }
3290}
3291
3292unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3293 return CXReparse_None;
3294}
3295
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003296static CXErrorCode
3297clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3298 ArrayRef<CXUnsavedFile> unsaved_files,
3299 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003300 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003301 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003302 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003303 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003304 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 // Reset the associated diagnostics.
3307 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003308 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003310 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3312 setThreadBackgroundPriority();
3313
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003314 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003316
3317 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3318 new std::vector<ASTUnit::RemappedFile>());
3319
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 // Recover resources if we crash before exiting this function.
3321 llvm::CrashRecoveryContextCleanupRegistrar<
3322 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003323
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003324 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003325 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003326 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003327 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003329
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003330 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3331 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003332 return CXError_Success;
3333 if (isASTReadError(CXXUnit))
3334 return CXError_ASTReadError;
3335 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336}
3337
3338int clang_reparseTranslationUnit(CXTranslationUnit TU,
3339 unsigned num_unsaved_files,
3340 struct CXUnsavedFile *unsaved_files,
3341 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003342 LOG_FUNC_SECTION {
3343 *Log << TU;
3344 }
3345
Alp Toker9d85b182014-07-07 01:23:14 +00003346 if (num_unsaved_files && !unsaved_files)
3347 return CXError_InvalidArguments;
3348
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003349 CXErrorCode result;
3350 auto ReparseTranslationUnitImpl = [=, &result]() {
3351 result = clang_reparseTranslationUnit_Impl(
3352 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3353 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003356 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003357 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359
3360 llvm::CrashRecoveryContext CRC;
3361
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003362 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003364 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003365 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3367 PrintLibclangResourceUsage(TU);
3368
Alp Toker5c532982014-07-07 22:42:03 +00003369 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370}
3371
3372
3373CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003374 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003375 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003376 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003377 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003378
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003379 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381}
3382
3383CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003384 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003385 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003386 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003387 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003388
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003389 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3391}
3392
3393} // end: extern "C"
3394
3395//===----------------------------------------------------------------------===//
3396// CXFile Operations.
3397//===----------------------------------------------------------------------===//
3398
3399extern "C" {
3400CXString clang_getFileName(CXFile SFile) {
3401 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003402 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003403
3404 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003405 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003406}
3407
3408time_t clang_getFileTime(CXFile SFile) {
3409 if (!SFile)
3410 return 0;
3411
3412 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3413 return FEnt->getModificationTime();
3414}
3415
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003416CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003417 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003418 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003419 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003420 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003422 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
3424 FileManager &FMgr = CXXUnit->getFileManager();
3425 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3426}
3427
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003428unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3429 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003430 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003431 LOG_BAD_TU(TU);
3432 return 0;
3433 }
3434
3435 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 return 0;
3437
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003438 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 FileEntry *FEnt = static_cast<FileEntry *>(file);
3440 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3441 .isFileMultipleIncludeGuarded(FEnt);
3442}
3443
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003444int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3445 if (!file || !outID)
3446 return 1;
3447
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003448 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003449 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3450 outID->data[0] = ID.getDevice();
3451 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003452 outID->data[2] = FEnt->getModificationTime();
3453 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003454}
3455
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003456int clang_File_isEqual(CXFile file1, CXFile file2) {
3457 if (file1 == file2)
3458 return true;
3459
3460 if (!file1 || !file2)
3461 return false;
3462
3463 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3464 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3465 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3466}
3467
Guy Benyei11169dd2012-12-18 14:30:41 +00003468} // end: extern "C"
3469
3470//===----------------------------------------------------------------------===//
3471// CXCursor Operations.
3472//===----------------------------------------------------------------------===//
3473
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003474static const Decl *getDeclFromExpr(const Stmt *E) {
3475 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 return getDeclFromExpr(CE->getSubExpr());
3477
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 if (PRE->isExplicitProperty())
3486 return PRE->getExplicitProperty();
3487 // It could be messaging both getter and setter as in:
3488 // ++myobj.myprop;
3489 // in which case prefer to associate the setter since it is less obvious
3490 // from inspecting the source that the setter is going to get called.
3491 if (PRE->isMessagingSetter())
3492 return PRE->getImplicitPropertySetter();
3493 return PRE->getImplicitPropertyGetter();
3494 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 if (Expr *Src = OVE->getSourceExpr())
3499 return getDeclFromExpr(Src);
3500
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 if (!CE->isElidable())
3505 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return OME->getMethodDecl();
3508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3513 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003514 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3516 isa<ParmVarDecl>(SizeOfPack->getPack()))
3517 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003518
3519 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520}
3521
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003522static SourceLocation getLocationFromExpr(const Expr *E) {
3523 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return getLocationFromExpr(CE->getSubExpr());
3525
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003526 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003528 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003530 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003534 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003536 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 return PropRef->getLocation();
3538
3539 return E->getLocStart();
3540}
3541
3542extern "C" {
3543
3544unsigned clang_visitChildren(CXCursor parent,
3545 CXCursorVisitor visitor,
3546 CXClientData client_data) {
3547 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3548 /*VisitPreprocessorLast=*/false);
3549 return CursorVis.VisitChildren(parent);
3550}
3551
3552#ifndef __has_feature
3553#define __has_feature(x) 0
3554#endif
3555#if __has_feature(blocks)
3556typedef enum CXChildVisitResult
3557 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3558
3559static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3560 CXClientData client_data) {
3561 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3562 return block(cursor, parent);
3563}
3564#else
3565// If we are compiled with a compiler that doesn't have native blocks support,
3566// define and call the block manually, so the
3567typedef struct _CXChildVisitResult
3568{
3569 void *isa;
3570 int flags;
3571 int reserved;
3572 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3573 CXCursor);
3574} *CXCursorVisitorBlock;
3575
3576static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3577 CXClientData client_data) {
3578 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3579 return block->invoke(block, cursor, parent);
3580}
3581#endif
3582
3583
3584unsigned clang_visitChildrenWithBlock(CXCursor parent,
3585 CXCursorVisitorBlock block) {
3586 return clang_visitChildren(parent, visitWithBlock, block);
3587}
3588
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003589static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003591 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003595 if (const ObjCPropertyImplDecl *PropImpl =
3596 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003602 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003603
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003604 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 }
3606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003607 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003608 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003610 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3612 // and returns different names. NamedDecl returns the class name and
3613 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615
3616 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003617 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003618
3619 SmallString<1024> S;
3620 llvm::raw_svector_ostream os(S);
3621 ND->printName(os);
3622
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624}
3625
3626CXString clang_getCursorSpelling(CXCursor C) {
3627 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003628 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003629
3630 if (clang_isReference(C.kind)) {
3631 switch (C.kind) {
3632 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 }
3636 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003637 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 }
3640 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003641 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 }
3645 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003646 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003647 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 }
3649 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003650 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 assert(Type && "Missing type decl");
3652
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 getAsString());
3655 }
3656 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003657 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 assert(Template && "Missing template decl");
3659
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 }
3662
3663 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003664 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 assert(NS && "Missing namespace decl");
3666
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 }
3669
3670 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003671 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 assert(Field && "Missing member decl");
3673
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003674 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676
3677 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003678 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 assert(Label && "Missing label");
3680
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 }
3683
3684 case CXCursor_OverloadedDeclRef: {
3685 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003686 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3687 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003688 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003689 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003691 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003692 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 OverloadedTemplateStorage *Ovl
3694 = Storage.get<OverloadedTemplateStorage*>();
3695 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003696 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003697 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 }
3699
3700 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003701 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 assert(Var && "Missing variable decl");
3703
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003704 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 }
3706
3707 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 }
3710 }
3711
3712 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003713 const Expr *E = getCursorExpr(C);
3714
3715 if (C.kind == CXCursor_ObjCStringLiteral ||
3716 C.kind == CXCursor_StringLiteral) {
3717 const StringLiteral *SLit;
3718 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3719 SLit = OSL->getString();
3720 } else {
3721 SLit = cast<StringLiteral>(E);
3722 }
3723 SmallString<256> Buf;
3724 llvm::raw_svector_ostream OS(Buf);
3725 SLit->outputString(OS);
3726 return cxstring::createDup(OS.str());
3727 }
3728
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003729 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 if (D)
3731 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003732 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 }
3734
3735 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003736 const Stmt *S = getCursorStmt(C);
3737 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003739
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003740 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 }
3742
3743 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 ->getNameStart());
3746
3747 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 ->getNameStart());
3750
3751 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003752 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003753
3754 if (clang_isDeclaration(C.kind))
3755 return getDeclSpelling(getCursorDecl(C));
3756
3757 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003758 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003759 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 }
3761
3762 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003763 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003764 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 }
3766
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003767 if (C.kind == CXCursor_PackedAttr) {
3768 return cxstring::createRef("packed");
3769 }
3770
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003771 if (C.kind == CXCursor_VisibilityAttr) {
3772 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3773 switch (AA->getVisibility()) {
3774 case VisibilityAttr::VisibilityType::Default:
3775 return cxstring::createRef("default");
3776 case VisibilityAttr::VisibilityType::Hidden:
3777 return cxstring::createRef("hidden");
3778 case VisibilityAttr::VisibilityType::Protected:
3779 return cxstring::createRef("protected");
3780 }
3781 llvm_unreachable("unknown visibility type");
3782 }
3783
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003784 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003785}
3786
3787CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3788 unsigned pieceIndex,
3789 unsigned options) {
3790 if (clang_Cursor_isNull(C))
3791 return clang_getNullRange();
3792
3793 ASTContext &Ctx = getCursorContext(C);
3794
3795 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003796 const Stmt *S = getCursorStmt(C);
3797 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 if (pieceIndex > 0)
3799 return clang_getNullRange();
3800 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3801 }
3802
3803 return clang_getNullRange();
3804 }
3805
3806 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003807 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3809 if (pieceIndex >= ME->getNumSelectorLocs())
3810 return clang_getNullRange();
3811 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3812 }
3813 }
3814
3815 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3816 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003817 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3819 if (pieceIndex >= MD->getNumSelectorLocs())
3820 return clang_getNullRange();
3821 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3822 }
3823 }
3824
3825 if (C.kind == CXCursor_ObjCCategoryDecl ||
3826 C.kind == CXCursor_ObjCCategoryImplDecl) {
3827 if (pieceIndex > 0)
3828 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003829 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3831 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003832 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3834 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3835 }
3836
3837 if (C.kind == CXCursor_ModuleImportDecl) {
3838 if (pieceIndex > 0)
3839 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003840 if (const ImportDecl *ImportD =
3841 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3843 if (!Locs.empty())
3844 return cxloc::translateSourceRange(Ctx,
3845 SourceRange(Locs.front(), Locs.back()));
3846 }
3847 return clang_getNullRange();
3848 }
3849
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003850 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3851 C.kind == CXCursor_ConversionFunction) {
3852 if (pieceIndex > 0)
3853 return clang_getNullRange();
3854 if (const FunctionDecl *FD =
3855 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3856 DeclarationNameInfo FunctionName = FD->getNameInfo();
3857 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3858 }
3859 return clang_getNullRange();
3860 }
3861
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 // FIXME: A CXCursor_InclusionDirective should give the location of the
3863 // filename, but we don't keep track of this.
3864
3865 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3866 // but we don't keep track of this.
3867
3868 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3869 // but we don't keep track of this.
3870
3871 // Default handling, give the location of the cursor.
3872
3873 if (pieceIndex > 0)
3874 return clang_getNullRange();
3875
3876 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3877 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3878 return cxloc::translateSourceRange(Ctx, Loc);
3879}
3880
Eli Bendersky44a206f2014-07-31 18:04:56 +00003881CXString clang_Cursor_getMangling(CXCursor C) {
3882 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3883 return cxstring::createEmpty();
3884
Eli Bendersky44a206f2014-07-31 18:04:56 +00003885 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003886 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003887 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3888 return cxstring::createEmpty();
3889
Eli Bendersky79759592014-08-01 15:01:10 +00003890 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003891 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003892 ASTContext &Ctx = ND->getASTContext();
3893 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003894
Eli Bendersky79759592014-08-01 15:01:10 +00003895 std::string FrontendBuf;
3896 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3897 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003898
Eli Bendersky79759592014-08-01 15:01:10 +00003899 // Now apply backend mangling.
3900 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003901 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003902
3903 std::string FinalBuf;
3904 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003905 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3906 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003907
3908 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003909}
3910
Guy Benyei11169dd2012-12-18 14:30:41 +00003911CXString clang_getCursorDisplayName(CXCursor C) {
3912 if (!clang_isDeclaration(C.kind))
3913 return clang_getCursorSpelling(C);
3914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003917 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003918
3919 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 D = FunTmpl->getTemplatedDecl();
3922
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003923 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 SmallString<64> Str;
3925 llvm::raw_svector_ostream OS(Str);
3926 OS << *Function;
3927 if (Function->getPrimaryTemplate())
3928 OS << "<>";
3929 OS << "(";
3930 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3931 if (I)
3932 OS << ", ";
3933 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3934 }
3935
3936 if (Function->isVariadic()) {
3937 if (Function->getNumParams())
3938 OS << ", ";
3939 OS << "...";
3940 }
3941 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003942 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 }
3944
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003945 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 SmallString<64> Str;
3947 llvm::raw_svector_ostream OS(Str);
3948 OS << *ClassTemplate;
3949 OS << "<";
3950 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3951 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3952 if (I)
3953 OS << ", ";
3954
3955 NamedDecl *Param = Params->getParam(I);
3956 if (Param->getIdentifier()) {
3957 OS << Param->getIdentifier()->getName();
3958 continue;
3959 }
3960
3961 // There is no parameter name, which makes this tricky. Try to come up
3962 // with something useful that isn't too long.
3963 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3964 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3965 else if (NonTypeTemplateParmDecl *NTTP
3966 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3967 OS << NTTP->getType().getAsString(Policy);
3968 else
3969 OS << "template<...> class";
3970 }
3971
3972 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003973 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 }
3975
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003976 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3978 // If the type was explicitly written, use that.
3979 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003980 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003981
Benjamin Kramer9170e912013-02-22 15:46:01 +00003982 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 llvm::raw_svector_ostream OS(Str);
3984 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003985 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 ClassSpec->getTemplateArgs().data(),
3987 ClassSpec->getTemplateArgs().size(),
3988 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003989 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 }
3991
3992 return clang_getCursorSpelling(C);
3993}
3994
3995CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3996 switch (Kind) {
3997 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004075 case CXCursor_OMPArraySectionExpr:
4076 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004127 case CXCursor_ObjCSelfExpr:
4128 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004217 case CXCursor_SEHLeaveStmt:
4218 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004247 case CXCursor_PackedAttr:
4248 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004249 case CXCursor_PureAttr:
4250 return cxstring::createRef("attribute(pure)");
4251 case CXCursor_ConstAttr:
4252 return cxstring::createRef("attribute(const)");
4253 case CXCursor_NoDuplicateAttr:
4254 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004255 case CXCursor_CUDAConstantAttr:
4256 return cxstring::createRef("attribute(constant)");
4257 case CXCursor_CUDADeviceAttr:
4258 return cxstring::createRef("attribute(device)");
4259 case CXCursor_CUDAGlobalAttr:
4260 return cxstring::createRef("attribute(global)");
4261 case CXCursor_CUDAHostAttr:
4262 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004263 case CXCursor_CUDASharedAttr:
4264 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004265 case CXCursor_VisibilityAttr:
4266 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004315 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004316 return cxstring::createRef("OMPParallelDirective");
4317 case CXCursor_OMPSimdDirective:
4318 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004319 case CXCursor_OMPForDirective:
4320 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004321 case CXCursor_OMPForSimdDirective:
4322 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004323 case CXCursor_OMPSectionsDirective:
4324 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004325 case CXCursor_OMPSectionDirective:
4326 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004327 case CXCursor_OMPSingleDirective:
4328 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004329 case CXCursor_OMPMasterDirective:
4330 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004331 case CXCursor_OMPCriticalDirective:
4332 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004333 case CXCursor_OMPParallelForDirective:
4334 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004335 case CXCursor_OMPParallelForSimdDirective:
4336 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004337 case CXCursor_OMPParallelSectionsDirective:
4338 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004339 case CXCursor_OMPTaskDirective:
4340 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004341 case CXCursor_OMPTaskyieldDirective:
4342 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004343 case CXCursor_OMPBarrierDirective:
4344 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004345 case CXCursor_OMPTaskwaitDirective:
4346 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004347 case CXCursor_OMPTaskgroupDirective:
4348 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004349 case CXCursor_OMPFlushDirective:
4350 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004351 case CXCursor_OMPOrderedDirective:
4352 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004353 case CXCursor_OMPAtomicDirective:
4354 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004355 case CXCursor_OMPTargetDirective:
4356 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004357 case CXCursor_OMPTargetDataDirective:
4358 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004359 case CXCursor_OMPTeamsDirective:
4360 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004361 case CXCursor_OMPCancellationPointDirective:
4362 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004363 case CXCursor_OMPCancelDirective:
4364 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004365 case CXCursor_OverloadCandidate:
4366 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 }
4368
4369 llvm_unreachable("Unhandled CXCursorKind");
4370}
4371
4372struct GetCursorData {
4373 SourceLocation TokenBeginLoc;
4374 bool PointsAtMacroArgExpansion;
4375 bool VisitedObjCPropertyImplDecl;
4376 SourceLocation VisitedDeclaratorDeclStartLoc;
4377 CXCursor &BestCursor;
4378
4379 GetCursorData(SourceManager &SM,
4380 SourceLocation tokenBegin, CXCursor &outputCursor)
4381 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4382 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4383 VisitedObjCPropertyImplDecl = false;
4384 }
4385};
4386
4387static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4388 CXCursor parent,
4389 CXClientData client_data) {
4390 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4391 CXCursor *BestCursor = &Data->BestCursor;
4392
4393 // If we point inside a macro argument we should provide info of what the
4394 // token is so use the actual cursor, don't replace it with a macro expansion
4395 // cursor.
4396 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4397 return CXChildVisit_Recurse;
4398
4399 if (clang_isDeclaration(cursor.kind)) {
4400 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4403 if (MD->isImplicit())
4404 return CXChildVisit_Break;
4405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4408 // Check that when we have multiple @class references in the same line,
4409 // that later ones do not override the previous ones.
4410 // If we have:
4411 // @class Foo, Bar;
4412 // source ranges for both start at '@', so 'Bar' will end up overriding
4413 // 'Foo' even though the cursor location was at 'Foo'.
4414 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4415 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004416 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4418 if (PrevID != ID &&
4419 !PrevID->isThisDeclarationADefinition() &&
4420 !ID->isThisDeclarationADefinition())
4421 return CXChildVisit_Break;
4422 }
4423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4426 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4427 // Check that when we have multiple declarators in the same line,
4428 // that later ones do not override the previous ones.
4429 // If we have:
4430 // int Foo, Bar;
4431 // source ranges for both start at 'int', so 'Bar' will end up overriding
4432 // 'Foo' even though the cursor location was at 'Foo'.
4433 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4434 return CXChildVisit_Break;
4435 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4436
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4439 (void)PropImp;
4440 // Check that when we have multiple @synthesize in the same line,
4441 // that later ones do not override the previous ones.
4442 // If we have:
4443 // @synthesize Foo, Bar;
4444 // source ranges for both start at '@', so 'Bar' will end up overriding
4445 // 'Foo' even though the cursor location was at 'Foo'.
4446 if (Data->VisitedObjCPropertyImplDecl)
4447 return CXChildVisit_Break;
4448 Data->VisitedObjCPropertyImplDecl = true;
4449 }
4450 }
4451
4452 if (clang_isExpression(cursor.kind) &&
4453 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 // Avoid having the cursor of an expression replace the declaration cursor
4456 // when the expression source range overlaps the declaration range.
4457 // This can happen for C++ constructor expressions whose range generally
4458 // include the variable declaration, e.g.:
4459 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4460 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4461 D->getLocation() == Data->TokenBeginLoc)
4462 return CXChildVisit_Break;
4463 }
4464 }
4465
4466 // If our current best cursor is the construction of a temporary object,
4467 // don't replace that cursor with a type reference, because we want
4468 // clang_getCursor() to point at the constructor.
4469 if (clang_isExpression(BestCursor->kind) &&
4470 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4471 cursor.kind == CXCursor_TypeRef) {
4472 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4473 // as having the actual point on the type reference.
4474 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4475 return CXChildVisit_Recurse;
4476 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004477
4478 // If we already have an Objective-C superclass reference, don't
4479 // update it further.
4480 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4481 return CXChildVisit_Break;
4482
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 *BestCursor = cursor;
4484 return CXChildVisit_Recurse;
4485}
4486
4487CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004488 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004489 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004491 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004492
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004493 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4495
4496 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4497 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4498
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004499 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 CXFile SearchFile;
4501 unsigned SearchLine, SearchColumn;
4502 CXFile ResultFile;
4503 unsigned ResultLine, ResultColumn;
4504 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4505 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4506 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004507
4508 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4509 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004510 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004511 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 SearchFileName = clang_getFileName(SearchFile);
4513 ResultFileName = clang_getFileName(ResultFile);
4514 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4515 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004516 *Log << llvm::format("(%s:%d:%d) = %s",
4517 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4518 clang_getCString(KindSpelling))
4519 << llvm::format("(%s:%d:%d):%s%s",
4520 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4521 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 clang_disposeString(SearchFileName);
4523 clang_disposeString(ResultFileName);
4524 clang_disposeString(KindSpelling);
4525 clang_disposeString(USR);
4526
4527 CXCursor Definition = clang_getCursorDefinition(Result);
4528 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4529 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4530 CXString DefinitionKindSpelling
4531 = clang_getCursorKindSpelling(Definition.kind);
4532 CXFile DefinitionFile;
4533 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004534 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004535 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004537 *Log << llvm::format(" -> %s(%s:%d:%d)",
4538 clang_getCString(DefinitionKindSpelling),
4539 clang_getCString(DefinitionFileName),
4540 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 clang_disposeString(DefinitionFileName);
4542 clang_disposeString(DefinitionKindSpelling);
4543 }
4544 }
4545
4546 return Result;
4547}
4548
4549CXCursor clang_getNullCursor(void) {
4550 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4551}
4552
4553unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004554 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4555 // can't set consistently. For example, when visiting a DeclStmt we will set
4556 // it but we don't set it on the result of clang_getCursorDefinition for
4557 // a reference of the same declaration.
4558 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4559 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4560 // to provide that kind of info.
4561 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004562 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004563 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004564 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004565
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 return X == Y;
4567}
4568
4569unsigned clang_hashCursor(CXCursor C) {
4570 unsigned Index = 0;
4571 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4572 Index = 1;
4573
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004574 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 std::make_pair(C.kind, C.data[Index]));
4576}
4577
4578unsigned clang_isInvalid(enum CXCursorKind K) {
4579 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4580}
4581
4582unsigned clang_isDeclaration(enum CXCursorKind K) {
4583 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4584 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4585}
4586
4587unsigned clang_isReference(enum CXCursorKind K) {
4588 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4589}
4590
4591unsigned clang_isExpression(enum CXCursorKind K) {
4592 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4593}
4594
4595unsigned clang_isStatement(enum CXCursorKind K) {
4596 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4597}
4598
4599unsigned clang_isAttribute(enum CXCursorKind K) {
4600 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4601}
4602
4603unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4604 return K == CXCursor_TranslationUnit;
4605}
4606
4607unsigned clang_isPreprocessing(enum CXCursorKind K) {
4608 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4609}
4610
4611unsigned clang_isUnexposed(enum CXCursorKind K) {
4612 switch (K) {
4613 case CXCursor_UnexposedDecl:
4614 case CXCursor_UnexposedExpr:
4615 case CXCursor_UnexposedStmt:
4616 case CXCursor_UnexposedAttr:
4617 return true;
4618 default:
4619 return false;
4620 }
4621}
4622
4623CXCursorKind clang_getCursorKind(CXCursor C) {
4624 return C.kind;
4625}
4626
4627CXSourceLocation clang_getCursorLocation(CXCursor C) {
4628 if (clang_isReference(C.kind)) {
4629 switch (C.kind) {
4630 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004631 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 = getCursorObjCSuperClassRef(C);
4633 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4634 }
4635
4636 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004637 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 = getCursorObjCProtocolRef(C);
4639 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4640 }
4641
4642 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004643 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 = getCursorObjCClassRef(C);
4645 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4646 }
4647
4648 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004649 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4651 }
4652
4653 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004654 std::pair<const TemplateDecl *, SourceLocation> P =
4655 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4657 }
4658
4659 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004660 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4662 }
4663
4664 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004665 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4667 }
4668
4669 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004670 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4672 }
4673
4674 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004675 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 if (!BaseSpec)
4677 return clang_getNullLocation();
4678
4679 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4680 return cxloc::translateSourceLocation(getCursorContext(C),
4681 TSInfo->getTypeLoc().getBeginLoc());
4682
4683 return cxloc::translateSourceLocation(getCursorContext(C),
4684 BaseSpec->getLocStart());
4685 }
4686
4687 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004688 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4690 }
4691
4692 case CXCursor_OverloadedDeclRef:
4693 return cxloc::translateSourceLocation(getCursorContext(C),
4694 getCursorOverloadedDeclRef(C).second);
4695
4696 default:
4697 // FIXME: Need a way to enumerate all non-reference cases.
4698 llvm_unreachable("Missed a reference kind");
4699 }
4700 }
4701
4702 if (clang_isExpression(C.kind))
4703 return cxloc::translateSourceLocation(getCursorContext(C),
4704 getLocationFromExpr(getCursorExpr(C)));
4705
4706 if (clang_isStatement(C.kind))
4707 return cxloc::translateSourceLocation(getCursorContext(C),
4708 getCursorStmt(C)->getLocStart());
4709
4710 if (C.kind == CXCursor_PreprocessingDirective) {
4711 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4712 return cxloc::translateSourceLocation(getCursorContext(C), L);
4713 }
4714
4715 if (C.kind == CXCursor_MacroExpansion) {
4716 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004717 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 return cxloc::translateSourceLocation(getCursorContext(C), L);
4719 }
4720
4721 if (C.kind == CXCursor_MacroDefinition) {
4722 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4723 return cxloc::translateSourceLocation(getCursorContext(C), L);
4724 }
4725
4726 if (C.kind == CXCursor_InclusionDirective) {
4727 SourceLocation L
4728 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4729 return cxloc::translateSourceLocation(getCursorContext(C), L);
4730 }
4731
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004732 if (clang_isAttribute(C.kind)) {
4733 SourceLocation L
4734 = cxcursor::getCursorAttr(C)->getLocation();
4735 return cxloc::translateSourceLocation(getCursorContext(C), L);
4736 }
4737
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!clang_isDeclaration(C.kind))
4739 return clang_getNullLocation();
4740
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 if (!D)
4743 return clang_getNullLocation();
4744
4745 SourceLocation Loc = D->getLocation();
4746 // FIXME: Multiple variables declared in a single declaration
4747 // currently lack the information needed to correctly determine their
4748 // ranges when accounting for the type-specifier. We use context
4749 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4750 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004751 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 if (!cxcursor::isFirstInDeclGroup(C))
4753 Loc = VD->getLocation();
4754 }
4755
4756 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004757 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 Loc = MD->getSelectorStartLoc();
4759
4760 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4761}
4762
4763} // end extern "C"
4764
4765CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4766 assert(TU);
4767
4768 // Guard against an invalid SourceLocation, or we may assert in one
4769 // of the following calls.
4770 if (SLoc.isInvalid())
4771 return clang_getNullCursor();
4772
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004773 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004774
4775 // Translate the given source location to make it point at the beginning of
4776 // the token under the cursor.
4777 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4778 CXXUnit->getASTContext().getLangOpts());
4779
4780 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4781 if (SLoc.isValid()) {
4782 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4783 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4784 /*VisitPreprocessorLast=*/true,
4785 /*VisitIncludedEntities=*/false,
4786 SourceLocation(SLoc));
4787 CursorVis.visitFileRegion();
4788 }
4789
4790 return Result;
4791}
4792
4793static SourceRange getRawCursorExtent(CXCursor C) {
4794 if (clang_isReference(C.kind)) {
4795 switch (C.kind) {
4796 case CXCursor_ObjCSuperClassRef:
4797 return getCursorObjCSuperClassRef(C).second;
4798
4799 case CXCursor_ObjCProtocolRef:
4800 return getCursorObjCProtocolRef(C).second;
4801
4802 case CXCursor_ObjCClassRef:
4803 return getCursorObjCClassRef(C).second;
4804
4805 case CXCursor_TypeRef:
4806 return getCursorTypeRef(C).second;
4807
4808 case CXCursor_TemplateRef:
4809 return getCursorTemplateRef(C).second;
4810
4811 case CXCursor_NamespaceRef:
4812 return getCursorNamespaceRef(C).second;
4813
4814 case CXCursor_MemberRef:
4815 return getCursorMemberRef(C).second;
4816
4817 case CXCursor_CXXBaseSpecifier:
4818 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4819
4820 case CXCursor_LabelRef:
4821 return getCursorLabelRef(C).second;
4822
4823 case CXCursor_OverloadedDeclRef:
4824 return getCursorOverloadedDeclRef(C).second;
4825
4826 case CXCursor_VariableRef:
4827 return getCursorVariableRef(C).second;
4828
4829 default:
4830 // FIXME: Need a way to enumerate all non-reference cases.
4831 llvm_unreachable("Missed a reference kind");
4832 }
4833 }
4834
4835 if (clang_isExpression(C.kind))
4836 return getCursorExpr(C)->getSourceRange();
4837
4838 if (clang_isStatement(C.kind))
4839 return getCursorStmt(C)->getSourceRange();
4840
4841 if (clang_isAttribute(C.kind))
4842 return getCursorAttr(C)->getRange();
4843
4844 if (C.kind == CXCursor_PreprocessingDirective)
4845 return cxcursor::getCursorPreprocessingDirective(C);
4846
4847 if (C.kind == CXCursor_MacroExpansion) {
4848 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004849 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 return TU->mapRangeFromPreamble(Range);
4851 }
4852
4853 if (C.kind == CXCursor_MacroDefinition) {
4854 ASTUnit *TU = getCursorASTUnit(C);
4855 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4856 return TU->mapRangeFromPreamble(Range);
4857 }
4858
4859 if (C.kind == CXCursor_InclusionDirective) {
4860 ASTUnit *TU = getCursorASTUnit(C);
4861 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4862 return TU->mapRangeFromPreamble(Range);
4863 }
4864
4865 if (C.kind == CXCursor_TranslationUnit) {
4866 ASTUnit *TU = getCursorASTUnit(C);
4867 FileID MainID = TU->getSourceManager().getMainFileID();
4868 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4869 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4870 return SourceRange(Start, End);
4871 }
4872
4873 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 if (!D)
4876 return SourceRange();
4877
4878 SourceRange R = D->getSourceRange();
4879 // FIXME: Multiple variables declared in a single declaration
4880 // currently lack the information needed to correctly determine their
4881 // ranges when accounting for the type-specifier. We use context
4882 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4883 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 if (!cxcursor::isFirstInDeclGroup(C))
4886 R.setBegin(VD->getLocation());
4887 }
4888 return R;
4889 }
4890 return SourceRange();
4891}
4892
4893/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4894/// the decl-specifier-seq for declarations.
4895static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4896 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004897 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 if (!D)
4899 return SourceRange();
4900
4901 SourceRange R = D->getSourceRange();
4902
4903 // Adjust the start of the location for declarations preceded by
4904 // declaration specifiers.
4905 SourceLocation StartLoc;
4906 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4907 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4908 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4911 StartLoc = TI->getTypeLoc().getLocStart();
4912 }
4913
4914 if (StartLoc.isValid() && R.getBegin().isValid() &&
4915 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4916 R.setBegin(StartLoc);
4917
4918 // FIXME: Multiple variables declared in a single declaration
4919 // currently lack the information needed to correctly determine their
4920 // ranges when accounting for the type-specifier. We use context
4921 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4922 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004923 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 if (!cxcursor::isFirstInDeclGroup(C))
4925 R.setBegin(VD->getLocation());
4926 }
4927
4928 return R;
4929 }
4930
4931 return getRawCursorExtent(C);
4932}
4933
4934extern "C" {
4935
4936CXSourceRange clang_getCursorExtent(CXCursor C) {
4937 SourceRange R = getRawCursorExtent(C);
4938 if (R.isInvalid())
4939 return clang_getNullRange();
4940
4941 return cxloc::translateSourceRange(getCursorContext(C), R);
4942}
4943
4944CXCursor clang_getCursorReferenced(CXCursor C) {
4945 if (clang_isInvalid(C.kind))
4946 return clang_getNullCursor();
4947
4948 CXTranslationUnit tu = getCursorTU(C);
4949 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004950 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004951 if (!D)
4952 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004953 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 if (const ObjCPropertyImplDecl *PropImpl =
4956 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4958 return MakeCXCursor(Property, tu);
4959
4960 return C;
4961 }
4962
4963 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004964 const Expr *E = getCursorExpr(C);
4965 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 if (D) {
4967 CXCursor declCursor = MakeCXCursor(D, tu);
4968 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4969 declCursor);
4970 return declCursor;
4971 }
4972
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004973 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 return MakeCursorOverloadedDeclRef(Ovl, tu);
4975
4976 return clang_getNullCursor();
4977 }
4978
4979 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004980 const Stmt *S = getCursorStmt(C);
4981 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 if (LabelDecl *label = Goto->getLabel())
4983 if (LabelStmt *labelS = label->getStmt())
4984 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4985
4986 return clang_getNullCursor();
4987 }
Richard Smith66a81862015-05-04 02:25:31 +00004988
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004990 if (const MacroDefinitionRecord *Def =
4991 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return MakeMacroDefinitionCursor(Def, tu);
4993 }
4994
4995 if (!clang_isReference(C.kind))
4996 return clang_getNullCursor();
4997
4998 switch (C.kind) {
4999 case CXCursor_ObjCSuperClassRef:
5000 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5001
5002 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005003 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5004 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 return MakeCXCursor(Def, tu);
5006
5007 return MakeCXCursor(Prot, tu);
5008 }
5009
5010 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005011 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5012 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 return MakeCXCursor(Def, tu);
5014
5015 return MakeCXCursor(Class, tu);
5016 }
5017
5018 case CXCursor_TypeRef:
5019 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5020
5021 case CXCursor_TemplateRef:
5022 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5023
5024 case CXCursor_NamespaceRef:
5025 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5026
5027 case CXCursor_MemberRef:
5028 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5029
5030 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005031 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5033 tu ));
5034 }
5035
5036 case CXCursor_LabelRef:
5037 // FIXME: We end up faking the "parent" declaration here because we
5038 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005039 return MakeCXCursor(getCursorLabelRef(C).first,
5040 cxtu::getASTUnit(tu)->getASTContext()
5041 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 tu);
5043
5044 case CXCursor_OverloadedDeclRef:
5045 return C;
5046
5047 case CXCursor_VariableRef:
5048 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5049
5050 default:
5051 // We would prefer to enumerate all non-reference cursor kinds here.
5052 llvm_unreachable("Unhandled reference cursor kind");
5053 }
5054}
5055
5056CXCursor clang_getCursorDefinition(CXCursor C) {
5057 if (clang_isInvalid(C.kind))
5058 return clang_getNullCursor();
5059
5060 CXTranslationUnit TU = getCursorTU(C);
5061
5062 bool WasReference = false;
5063 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5064 C = clang_getCursorReferenced(C);
5065 WasReference = true;
5066 }
5067
5068 if (C.kind == CXCursor_MacroExpansion)
5069 return clang_getCursorReferenced(C);
5070
5071 if (!clang_isDeclaration(C.kind))
5072 return clang_getNullCursor();
5073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 if (!D)
5076 return clang_getNullCursor();
5077
5078 switch (D->getKind()) {
5079 // Declaration kinds that don't really separate the notions of
5080 // declaration and definition.
5081 case Decl::Namespace:
5082 case Decl::Typedef:
5083 case Decl::TypeAlias:
5084 case Decl::TypeAliasTemplate:
5085 case Decl::TemplateTypeParm:
5086 case Decl::EnumConstant:
5087 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005088 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 case Decl::IndirectField:
5090 case Decl::ObjCIvar:
5091 case Decl::ObjCAtDefsField:
5092 case Decl::ImplicitParam:
5093 case Decl::ParmVar:
5094 case Decl::NonTypeTemplateParm:
5095 case Decl::TemplateTemplateParm:
5096 case Decl::ObjCCategoryImpl:
5097 case Decl::ObjCImplementation:
5098 case Decl::AccessSpec:
5099 case Decl::LinkageSpec:
5100 case Decl::ObjCPropertyImpl:
5101 case Decl::FileScopeAsm:
5102 case Decl::StaticAssert:
5103 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005104 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 case Decl::Label: // FIXME: Is this right??
5106 case Decl::ClassScopeFunctionSpecialization:
5107 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005108 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005109 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 return C;
5111
5112 // Declaration kinds that don't make any sense here, but are
5113 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005114 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005116 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 break;
5118
5119 // Declaration kinds for which the definition is not resolvable.
5120 case Decl::UnresolvedUsingTypename:
5121 case Decl::UnresolvedUsingValue:
5122 break;
5123
5124 case Decl::UsingDirective:
5125 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5126 TU);
5127
5128 case Decl::NamespaceAlias:
5129 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5130
5131 case Decl::Enum:
5132 case Decl::Record:
5133 case Decl::CXXRecord:
5134 case Decl::ClassTemplateSpecialization:
5135 case Decl::ClassTemplatePartialSpecialization:
5136 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5137 return MakeCXCursor(Def, TU);
5138 return clang_getNullCursor();
5139
5140 case Decl::Function:
5141 case Decl::CXXMethod:
5142 case Decl::CXXConstructor:
5143 case Decl::CXXDestructor:
5144 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005145 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005147 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 return clang_getNullCursor();
5149 }
5150
Larisse Voufo39a1e502013-08-06 01:03:05 +00005151 case Decl::Var:
5152 case Decl::VarTemplateSpecialization:
5153 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005155 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 return MakeCXCursor(Def, TU);
5157 return clang_getNullCursor();
5158 }
5159
5160 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005161 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5163 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5164 return clang_getNullCursor();
5165 }
5166
5167 case Decl::ClassTemplate: {
5168 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5169 ->getDefinition())
5170 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5171 TU);
5172 return clang_getNullCursor();
5173 }
5174
Larisse Voufo39a1e502013-08-06 01:03:05 +00005175 case Decl::VarTemplate: {
5176 if (VarDecl *Def =
5177 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5178 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5179 return clang_getNullCursor();
5180 }
5181
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case Decl::Using:
5183 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5184 D->getLocation(), TU);
5185
5186 case Decl::UsingShadow:
5187 return clang_getCursorDefinition(
5188 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5189 TU));
5190
5191 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005192 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 if (Method->isThisDeclarationADefinition())
5194 return C;
5195
5196 // Dig out the method definition in the associated
5197 // @implementation, if we have it.
5198 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005199 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5201 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5202 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5203 Method->isInstanceMethod()))
5204 if (Def->isThisDeclarationADefinition())
5205 return MakeCXCursor(Def, TU);
5206
5207 return clang_getNullCursor();
5208 }
5209
5210 case Decl::ObjCCategory:
5211 if (ObjCCategoryImplDecl *Impl
5212 = cast<ObjCCategoryDecl>(D)->getImplementation())
5213 return MakeCXCursor(Impl, TU);
5214 return clang_getNullCursor();
5215
5216 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005217 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 return MakeCXCursor(Def, TU);
5219 return clang_getNullCursor();
5220
5221 case Decl::ObjCInterface: {
5222 // There are two notions of a "definition" for an Objective-C
5223 // class: the interface and its implementation. When we resolved a
5224 // reference to an Objective-C class, produce the @interface as
5225 // the definition; when we were provided with the interface,
5226 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005227 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 return MakeCXCursor(Def, TU);
5231 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5232 return MakeCXCursor(Impl, TU);
5233 return clang_getNullCursor();
5234 }
5235
5236 case Decl::ObjCProperty:
5237 // FIXME: We don't really know where to find the
5238 // ObjCPropertyImplDecls that implement this property.
5239 return clang_getNullCursor();
5240
5241 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005242 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005244 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 return MakeCXCursor(Def, TU);
5246
5247 return clang_getNullCursor();
5248
5249 case Decl::Friend:
5250 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5251 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5252 return clang_getNullCursor();
5253
5254 case Decl::FriendTemplate:
5255 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5256 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5257 return clang_getNullCursor();
5258 }
5259
5260 return clang_getNullCursor();
5261}
5262
5263unsigned clang_isCursorDefinition(CXCursor C) {
5264 if (!clang_isDeclaration(C.kind))
5265 return 0;
5266
5267 return clang_getCursorDefinition(C) == C;
5268}
5269
5270CXCursor clang_getCanonicalCursor(CXCursor C) {
5271 if (!clang_isDeclaration(C.kind))
5272 return C;
5273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005274 if (const Decl *D = getCursorDecl(C)) {
5275 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5277 return MakeCXCursor(CatD, getCursorTU(C));
5278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005279 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5280 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 return MakeCXCursor(IFD, getCursorTU(C));
5282
5283 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5284 }
5285
5286 return C;
5287}
5288
5289int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5290 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5291}
5292
5293unsigned clang_getNumOverloadedDecls(CXCursor C) {
5294 if (C.kind != CXCursor_OverloadedDeclRef)
5295 return 0;
5296
5297 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005298 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 return E->getNumDecls();
5300
5301 if (OverloadedTemplateStorage *S
5302 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5303 return S->size();
5304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005305 const Decl *D = Storage.get<const Decl *>();
5306 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 return Using->shadow_size();
5308
5309 return 0;
5310}
5311
5312CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5313 if (cursor.kind != CXCursor_OverloadedDeclRef)
5314 return clang_getNullCursor();
5315
5316 if (index >= clang_getNumOverloadedDecls(cursor))
5317 return clang_getNullCursor();
5318
5319 CXTranslationUnit TU = getCursorTU(cursor);
5320 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005321 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 return MakeCXCursor(E->decls_begin()[index], TU);
5323
5324 if (OverloadedTemplateStorage *S
5325 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5326 return MakeCXCursor(S->begin()[index], TU);
5327
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005328 const Decl *D = Storage.get<const Decl *>();
5329 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 // FIXME: This is, unfortunately, linear time.
5331 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5332 std::advance(Pos, index);
5333 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5334 }
5335
5336 return clang_getNullCursor();
5337}
5338
5339void clang_getDefinitionSpellingAndExtent(CXCursor C,
5340 const char **startBuf,
5341 const char **endBuf,
5342 unsigned *startLine,
5343 unsigned *startColumn,
5344 unsigned *endLine,
5345 unsigned *endColumn) {
5346 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005347 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5349
5350 SourceManager &SM = FD->getASTContext().getSourceManager();
5351 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5352 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5353 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5354 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5355 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5356 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5357}
5358
5359
5360CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5361 unsigned PieceIndex) {
5362 RefNamePieces Pieces;
5363
5364 switch (C.kind) {
5365 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005366 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5368 E->getQualifierLoc().getSourceRange());
5369 break;
5370
5371 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005372 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5374 E->getQualifierLoc().getSourceRange(),
5375 E->getOptionalExplicitTemplateArgs());
5376 break;
5377
5378 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005379 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005381 const Expr *Callee = OCE->getCallee();
5382 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 Callee = ICE->getSubExpr();
5384
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005385 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5387 DRE->getQualifierLoc().getSourceRange());
5388 }
5389 break;
5390
5391 default:
5392 break;
5393 }
5394
5395 if (Pieces.empty()) {
5396 if (PieceIndex == 0)
5397 return clang_getCursorExtent(C);
5398 } else if (PieceIndex < Pieces.size()) {
5399 SourceRange R = Pieces[PieceIndex];
5400 if (R.isValid())
5401 return cxloc::translateSourceRange(getCursorContext(C), R);
5402 }
5403
5404 return clang_getNullRange();
5405}
5406
5407void clang_enableStackTraces(void) {
5408 llvm::sys::PrintStackTraceOnErrorSignal();
5409}
5410
5411void clang_executeOnThread(void (*fn)(void*), void *user_data,
5412 unsigned stack_size) {
5413 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5414}
5415
5416} // end: extern "C"
5417
5418//===----------------------------------------------------------------------===//
5419// Token-based Operations.
5420//===----------------------------------------------------------------------===//
5421
5422/* CXToken layout:
5423 * int_data[0]: a CXTokenKind
5424 * int_data[1]: starting token location
5425 * int_data[2]: token length
5426 * int_data[3]: reserved
5427 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5428 * otherwise unused.
5429 */
5430extern "C" {
5431
5432CXTokenKind clang_getTokenKind(CXToken CXTok) {
5433 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5434}
5435
5436CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5437 switch (clang_getTokenKind(CXTok)) {
5438 case CXToken_Identifier:
5439 case CXToken_Keyword:
5440 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005441 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 ->getNameStart());
5443
5444 case CXToken_Literal: {
5445 // We have stashed the starting pointer in the ptr_data field. Use it.
5446 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005447 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 }
5449
5450 case CXToken_Punctuation:
5451 case CXToken_Comment:
5452 break;
5453 }
5454
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005455 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005456 LOG_BAD_TU(TU);
5457 return cxstring::createEmpty();
5458 }
5459
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 // We have to find the starting buffer pointer the hard way, by
5461 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005462 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005464 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005465
5466 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5467 std::pair<FileID, unsigned> LocInfo
5468 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5469 bool Invalid = false;
5470 StringRef Buffer
5471 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5472 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005474
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005475 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005476}
5477
5478CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005479 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005480 LOG_BAD_TU(TU);
5481 return clang_getNullLocation();
5482 }
5483
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005484 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 if (!CXXUnit)
5486 return clang_getNullLocation();
5487
5488 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5489 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5490}
5491
5492CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005493 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005494 LOG_BAD_TU(TU);
5495 return clang_getNullRange();
5496 }
5497
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005498 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 if (!CXXUnit)
5500 return clang_getNullRange();
5501
5502 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5503 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5504}
5505
5506static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5507 SmallVectorImpl<CXToken> &CXTokens) {
5508 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5509 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005510 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005512 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005513
5514 // Cannot tokenize across files.
5515 if (BeginLocInfo.first != EndLocInfo.first)
5516 return;
5517
5518 // Create a lexer
5519 bool Invalid = false;
5520 StringRef Buffer
5521 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5522 if (Invalid)
5523 return;
5524
5525 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5526 CXXUnit->getASTContext().getLangOpts(),
5527 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5528 Lex.SetCommentRetentionState(true);
5529
5530 // Lex tokens until we hit the end of the range.
5531 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5532 Token Tok;
5533 bool previousWasAt = false;
5534 do {
5535 // Lex the next token
5536 Lex.LexFromRawLexer(Tok);
5537 if (Tok.is(tok::eof))
5538 break;
5539
5540 // Initialize the CXToken.
5541 CXToken CXTok;
5542
5543 // - Common fields
5544 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5545 CXTok.int_data[2] = Tok.getLength();
5546 CXTok.int_data[3] = 0;
5547
5548 // - Kind-specific fields
5549 if (Tok.isLiteral()) {
5550 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005551 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 } else if (Tok.is(tok::raw_identifier)) {
5553 // Lookup the identifier to determine whether we have a keyword.
5554 IdentifierInfo *II
5555 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5556
5557 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5558 CXTok.int_data[0] = CXToken_Keyword;
5559 }
5560 else {
5561 CXTok.int_data[0] = Tok.is(tok::identifier)
5562 ? CXToken_Identifier
5563 : CXToken_Keyword;
5564 }
5565 CXTok.ptr_data = II;
5566 } else if (Tok.is(tok::comment)) {
5567 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005568 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 } else {
5570 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005571 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 }
5573 CXTokens.push_back(CXTok);
5574 previousWasAt = Tok.is(tok::at);
5575 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5576}
5577
5578void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5579 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005580 LOG_FUNC_SECTION {
5581 *Log << TU << ' ' << Range;
5582 }
5583
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005585 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 if (NumTokens)
5587 *NumTokens = 0;
5588
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005589 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005590 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005591 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005592 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005593
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005594 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 if (!CXXUnit || !Tokens || !NumTokens)
5596 return;
5597
5598 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5599
5600 SourceRange R = cxloc::translateCXSourceRange(Range);
5601 if (R.isInvalid())
5602 return;
5603
5604 SmallVector<CXToken, 32> CXTokens;
5605 getTokens(CXXUnit, R, CXTokens);
5606
5607 if (CXTokens.empty())
5608 return;
5609
5610 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5611 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5612 *NumTokens = CXTokens.size();
5613}
5614
5615void clang_disposeTokens(CXTranslationUnit TU,
5616 CXToken *Tokens, unsigned NumTokens) {
5617 free(Tokens);
5618}
5619
5620} // end: extern "C"
5621
5622//===----------------------------------------------------------------------===//
5623// Token annotation APIs.
5624//===----------------------------------------------------------------------===//
5625
Guy Benyei11169dd2012-12-18 14:30:41 +00005626static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5627 CXCursor parent,
5628 CXClientData client_data);
5629static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5630 CXClientData client_data);
5631
5632namespace {
5633class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 CXToken *Tokens;
5635 CXCursor *Cursors;
5636 unsigned NumTokens;
5637 unsigned TokIdx;
5638 unsigned PreprocessingTokIdx;
5639 CursorVisitor AnnotateVis;
5640 SourceManager &SrcMgr;
5641 bool HasContextSensitiveKeywords;
5642
5643 struct PostChildrenInfo {
5644 CXCursor Cursor;
5645 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005646 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 unsigned BeforeChildrenTokenIdx;
5648 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005649 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005650
5651 CXToken &getTok(unsigned Idx) {
5652 assert(Idx < NumTokens);
5653 return Tokens[Idx];
5654 }
5655 const CXToken &getTok(unsigned Idx) const {
5656 assert(Idx < NumTokens);
5657 return Tokens[Idx];
5658 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 bool MoreTokens() const { return TokIdx < NumTokens; }
5660 unsigned NextToken() const { return TokIdx; }
5661 void AdvanceToken() { ++TokIdx; }
5662 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005663 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 }
5665 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005666 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 }
5668 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005669 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 }
5671
5672 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005673 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 SourceRange);
5675
5676public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005677 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005678 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005681 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 AnnotateTokensVisitor, this,
5683 /*VisitPreprocessorLast=*/true,
5684 /*VisitIncludedEntities=*/false,
5685 RegionOfInterest,
5686 /*VisitDeclsOnly=*/false,
5687 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005688 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 HasContextSensitiveKeywords(false) { }
5690
5691 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5692 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5693 bool postVisitChildren(CXCursor cursor);
5694 void AnnotateTokens();
5695
5696 /// \brief Determine whether the annotator saw any cursors that have
5697 /// context-sensitive keywords.
5698 bool hasContextSensitiveKeywords() const {
5699 return HasContextSensitiveKeywords;
5700 }
5701
5702 ~AnnotateTokensWorker() {
5703 assert(PostChildrenInfos.empty());
5704 }
5705};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005706}
Guy Benyei11169dd2012-12-18 14:30:41 +00005707
5708void AnnotateTokensWorker::AnnotateTokens() {
5709 // Walk the AST within the region of interest, annotating tokens
5710 // along the way.
5711 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712}
Guy Benyei11169dd2012-12-18 14:30:41 +00005713
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714static inline void updateCursorAnnotation(CXCursor &Cursor,
5715 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005716 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005718 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005719}
5720
5721/// \brief It annotates and advances tokens with a cursor until the comparison
5722//// between the cursor location and the source range is the same as
5723/// \arg compResult.
5724///
5725/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5726/// Pass RangeOverlap to annotate tokens inside a range.
5727void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5728 RangeComparisonResult compResult,
5729 SourceRange range) {
5730 while (MoreTokens()) {
5731 const unsigned I = NextToken();
5732 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005733 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5734 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005735
5736 SourceLocation TokLoc = GetTokenLoc(I);
5737 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005738 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 AdvanceToken();
5740 continue;
5741 }
5742 break;
5743 }
5744}
5745
5746/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005747/// \returns true if it advanced beyond all macro tokens, false otherwise.
5748bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 CXCursor updateC,
5750 RangeComparisonResult compResult,
5751 SourceRange range) {
5752 assert(MoreTokens());
5753 assert(isFunctionMacroToken(NextToken()) &&
5754 "Should be called only for macro arg tokens");
5755
5756 // This works differently than annotateAndAdvanceTokens; because expanded
5757 // macro arguments can have arbitrary translation-unit source order, we do not
5758 // advance the token index one by one until a token fails the range test.
5759 // We only advance once past all of the macro arg tokens if all of them
5760 // pass the range test. If one of them fails we keep the token index pointing
5761 // at the start of the macro arg tokens so that the failing token will be
5762 // annotated by a subsequent annotation try.
5763
5764 bool atLeastOneCompFail = false;
5765
5766 unsigned I = NextToken();
5767 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5768 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5769 if (TokLoc.isFileID())
5770 continue; // not macro arg token, it's parens or comma.
5771 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5772 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5773 Cursors[I] = updateC;
5774 } else
5775 atLeastOneCompFail = true;
5776 }
5777
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005778 if (atLeastOneCompFail)
5779 return false;
5780
5781 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5782 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005783}
5784
5785enum CXChildVisitResult
5786AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 SourceRange cursorRange = getRawCursorExtent(cursor);
5788 if (cursorRange.isInvalid())
5789 return CXChildVisit_Recurse;
5790
5791 if (!HasContextSensitiveKeywords) {
5792 // Objective-C properties can have context-sensitive keywords.
5793 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005794 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5796 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5797 }
5798 // Objective-C methods can have context-sensitive keywords.
5799 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5800 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005801 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5803 if (Method->getObjCDeclQualifier())
5804 HasContextSensitiveKeywords = true;
5805 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005806 for (const auto *P : Method->params()) {
5807 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 HasContextSensitiveKeywords = true;
5809 break;
5810 }
5811 }
5812 }
5813 }
5814 }
5815 // C++ methods can have context-sensitive keywords.
5816 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005817 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5819 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5820 HasContextSensitiveKeywords = true;
5821 }
5822 }
5823 // C++ classes can have context-sensitive keywords.
5824 else if (cursor.kind == CXCursor_StructDecl ||
5825 cursor.kind == CXCursor_ClassDecl ||
5826 cursor.kind == CXCursor_ClassTemplate ||
5827 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005828 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 if (D->hasAttr<FinalAttr>())
5830 HasContextSensitiveKeywords = true;
5831 }
5832 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005833
5834 // Don't override a property annotation with its getter/setter method.
5835 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5836 parent.kind == CXCursor_ObjCPropertyDecl)
5837 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005838
5839 if (clang_isPreprocessing(cursor.kind)) {
5840 // Items in the preprocessing record are kept separate from items in
5841 // declarations, so we keep a separate token index.
5842 unsigned SavedTokIdx = TokIdx;
5843 TokIdx = PreprocessingTokIdx;
5844
5845 // Skip tokens up until we catch up to the beginning of the preprocessing
5846 // entry.
5847 while (MoreTokens()) {
5848 const unsigned I = NextToken();
5849 SourceLocation TokLoc = GetTokenLoc(I);
5850 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5851 case RangeBefore:
5852 AdvanceToken();
5853 continue;
5854 case RangeAfter:
5855 case RangeOverlap:
5856 break;
5857 }
5858 break;
5859 }
5860
5861 // Look at all of the tokens within this range.
5862 while (MoreTokens()) {
5863 const unsigned I = NextToken();
5864 SourceLocation TokLoc = GetTokenLoc(I);
5865 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5866 case RangeBefore:
5867 llvm_unreachable("Infeasible");
5868 case RangeAfter:
5869 break;
5870 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005871 // For macro expansions, just note where the beginning of the macro
5872 // expansion occurs.
5873 if (cursor.kind == CXCursor_MacroExpansion) {
5874 if (TokLoc == cursorRange.getBegin())
5875 Cursors[I] = cursor;
5876 AdvanceToken();
5877 break;
5878 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005879 // We may have already annotated macro names inside macro definitions.
5880 if (Cursors[I].kind != CXCursor_MacroExpansion)
5881 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 continue;
5884 }
5885 break;
5886 }
5887
5888 // Save the preprocessing token index; restore the non-preprocessing
5889 // token index.
5890 PreprocessingTokIdx = TokIdx;
5891 TokIdx = SavedTokIdx;
5892 return CXChildVisit_Recurse;
5893 }
5894
5895 if (cursorRange.isInvalid())
5896 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005897
5898 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005899 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 const enum CXCursorKind K = clang_getCursorKind(parent);
5901 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005902 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5903 // Attributes are annotated out-of-order, skip tokens until we reach it.
5904 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 ? clang_getNullCursor() : parent;
5906
5907 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5908
5909 // Avoid having the cursor of an expression "overwrite" the annotation of the
5910 // variable declaration that it belongs to.
5911 // This can happen for C++ constructor expressions whose range generally
5912 // include the variable declaration, e.g.:
5913 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005914 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005915 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005916 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 const unsigned I = NextToken();
5918 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5919 E->getLocStart() == D->getLocation() &&
5920 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005921 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 AdvanceToken();
5923 }
5924 }
5925 }
5926
5927 // Before recursing into the children keep some state that we are going
5928 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5929 // extra work after the child nodes are visited.
5930 // Note that we don't call VisitChildren here to avoid traversing statements
5931 // code-recursively which can blow the stack.
5932
5933 PostChildrenInfo Info;
5934 Info.Cursor = cursor;
5935 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005936 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 Info.BeforeChildrenTokenIdx = NextToken();
5938 PostChildrenInfos.push_back(Info);
5939
5940 return CXChildVisit_Recurse;
5941}
5942
5943bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5944 if (PostChildrenInfos.empty())
5945 return false;
5946 const PostChildrenInfo &Info = PostChildrenInfos.back();
5947 if (!clang_equalCursors(Info.Cursor, cursor))
5948 return false;
5949
5950 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5951 const unsigned AfterChildren = NextToken();
5952 SourceRange cursorRange = Info.CursorRange;
5953
5954 // Scan the tokens that are at the end of the cursor, but are not captured
5955 // but the child cursors.
5956 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5957
5958 // Scan the tokens that are at the beginning of the cursor, but are not
5959 // capture by the child cursors.
5960 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5961 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5962 break;
5963
5964 Cursors[I] = cursor;
5965 }
5966
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005967 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5968 // encountered the attribute cursor.
5969 if (clang_isAttribute(cursor.kind))
5970 TokIdx = Info.BeforeReachingCursorIdx;
5971
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 PostChildrenInfos.pop_back();
5973 return false;
5974}
5975
5976static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5977 CXCursor parent,
5978 CXClientData client_data) {
5979 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5980}
5981
5982static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5983 CXClientData client_data) {
5984 return static_cast<AnnotateTokensWorker*>(client_data)->
5985 postVisitChildren(cursor);
5986}
5987
5988namespace {
5989
5990/// \brief Uses the macro expansions in the preprocessing record to find
5991/// and mark tokens that are macro arguments. This info is used by the
5992/// AnnotateTokensWorker.
5993class MarkMacroArgTokensVisitor {
5994 SourceManager &SM;
5995 CXToken *Tokens;
5996 unsigned NumTokens;
5997 unsigned CurIdx;
5998
5999public:
6000 MarkMacroArgTokensVisitor(SourceManager &SM,
6001 CXToken *tokens, unsigned numTokens)
6002 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6003
6004 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6005 if (cursor.kind != CXCursor_MacroExpansion)
6006 return CXChildVisit_Continue;
6007
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006008 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006009 if (macroRange.getBegin() == macroRange.getEnd())
6010 return CXChildVisit_Continue; // it's not a function macro.
6011
6012 for (; CurIdx < NumTokens; ++CurIdx) {
6013 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6014 macroRange.getBegin()))
6015 break;
6016 }
6017
6018 if (CurIdx == NumTokens)
6019 return CXChildVisit_Break;
6020
6021 for (; CurIdx < NumTokens; ++CurIdx) {
6022 SourceLocation tokLoc = getTokenLoc(CurIdx);
6023 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6024 break;
6025
6026 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6027 }
6028
6029 if (CurIdx == NumTokens)
6030 return CXChildVisit_Break;
6031
6032 return CXChildVisit_Continue;
6033 }
6034
6035private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006036 CXToken &getTok(unsigned Idx) {
6037 assert(Idx < NumTokens);
6038 return Tokens[Idx];
6039 }
6040 const CXToken &getTok(unsigned Idx) const {
6041 assert(Idx < NumTokens);
6042 return Tokens[Idx];
6043 }
6044
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006046 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 }
6048
6049 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6050 // The third field is reserved and currently not used. Use it here
6051 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006052 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 }
6054};
6055
6056} // end anonymous namespace
6057
6058static CXChildVisitResult
6059MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6060 CXClientData client_data) {
6061 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6062 parent);
6063}
6064
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006065/// \brief Used by \c annotatePreprocessorTokens.
6066/// \returns true if lexing was finished, false otherwise.
6067static bool lexNext(Lexer &Lex, Token &Tok,
6068 unsigned &NextIdx, unsigned NumTokens) {
6069 if (NextIdx >= NumTokens)
6070 return true;
6071
6072 ++NextIdx;
6073 Lex.LexFromRawLexer(Tok);
6074 if (Tok.is(tok::eof))
6075 return true;
6076
6077 return false;
6078}
6079
Guy Benyei11169dd2012-12-18 14:30:41 +00006080static void annotatePreprocessorTokens(CXTranslationUnit TU,
6081 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006082 CXCursor *Cursors,
6083 CXToken *Tokens,
6084 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006085 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006087 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6089 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006090 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006092 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006093
6094 if (BeginLocInfo.first != EndLocInfo.first)
6095 return;
6096
6097 StringRef Buffer;
6098 bool Invalid = false;
6099 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6100 if (Buffer.empty() || Invalid)
6101 return;
6102
6103 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6104 CXXUnit->getASTContext().getLangOpts(),
6105 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6106 Buffer.end());
6107 Lex.SetCommentRetentionState(true);
6108
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006109 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 // Lex tokens in raw mode until we hit the end of the range, to avoid
6111 // entering #includes or expanding macros.
6112 while (true) {
6113 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006114 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6115 break;
6116 unsigned TokIdx = NextIdx-1;
6117 assert(Tok.getLocation() ==
6118 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006119
6120 reprocess:
6121 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006122 // We have found a preprocessing directive. Annotate the tokens
6123 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 //
6125 // FIXME: Some simple tests here could identify macro definitions and
6126 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006127
6128 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006129 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6130 break;
6131
Craig Topper69186e72014-06-08 08:38:04 +00006132 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006133 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006134 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6135 break;
6136
6137 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006138 IdentifierInfo &II =
6139 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006140 SourceLocation MappedTokLoc =
6141 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6142 MI = getMacroInfo(II, MappedTokLoc, TU);
6143 }
6144 }
6145
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006146 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006148 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6149 finished = true;
6150 break;
6151 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006152 // If we are in a macro definition, check if the token was ever a
6153 // macro name and annotate it if that's the case.
6154 if (MI) {
6155 SourceLocation SaveLoc = Tok.getLocation();
6156 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006157 MacroDefinitionRecord *MacroDef =
6158 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006159 Tok.setLocation(SaveLoc);
6160 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006161 Cursors[NextIdx - 1] =
6162 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006163 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006164 } while (!Tok.isAtStartOfLine());
6165
6166 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6167 assert(TokIdx <= LastIdx);
6168 SourceLocation EndLoc =
6169 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6170 CXCursor Cursor =
6171 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6172
6173 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006174 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006175
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006176 if (finished)
6177 break;
6178 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 }
6181}
6182
6183// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006184static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6185 CXToken *Tokens, unsigned NumTokens,
6186 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006187 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6189 setThreadBackgroundPriority();
6190
6191 // Determine the region of interest, which contains all of the tokens.
6192 SourceRange RegionOfInterest;
6193 RegionOfInterest.setBegin(
6194 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6195 RegionOfInterest.setEnd(
6196 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6197 Tokens[NumTokens-1])));
6198
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 // Relex the tokens within the source range to look for preprocessing
6200 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006201 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006202
6203 // If begin location points inside a macro argument, set it to the expansion
6204 // location so we can have the full context when annotating semantically.
6205 {
6206 SourceManager &SM = CXXUnit->getSourceManager();
6207 SourceLocation Loc =
6208 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6209 if (Loc.isMacroID())
6210 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6211 }
6212
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6214 // Search and mark tokens that are macro argument expansions.
6215 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6216 Tokens, NumTokens);
6217 CursorVisitor MacroArgMarker(TU,
6218 MarkMacroArgTokensVisitorDelegate, &Visitor,
6219 /*VisitPreprocessorLast=*/true,
6220 /*VisitIncludedEntities=*/false,
6221 RegionOfInterest);
6222 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6223 }
6224
6225 // Annotate all of the source locations in the region of interest that map to
6226 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006227 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006228
6229 // FIXME: We use a ridiculous stack size here because the data-recursion
6230 // algorithm uses a large stack frame than the non-data recursive version,
6231 // and AnnotationTokensWorker currently transforms the data-recursion
6232 // algorithm back into a traditional recursion by explicitly calling
6233 // VisitChildren(). We will need to remove this explicit recursive call.
6234 W.AnnotateTokens();
6235
6236 // If we ran into any entities that involve context-sensitive keywords,
6237 // take another pass through the tokens to mark them as such.
6238 if (W.hasContextSensitiveKeywords()) {
6239 for (unsigned I = 0; I != NumTokens; ++I) {
6240 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6241 continue;
6242
6243 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6244 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006245 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6247 if (Property->getPropertyAttributesAsWritten() != 0 &&
6248 llvm::StringSwitch<bool>(II->getName())
6249 .Case("readonly", true)
6250 .Case("assign", true)
6251 .Case("unsafe_unretained", true)
6252 .Case("readwrite", true)
6253 .Case("retain", true)
6254 .Case("copy", true)
6255 .Case("nonatomic", true)
6256 .Case("atomic", true)
6257 .Case("getter", true)
6258 .Case("setter", true)
6259 .Case("strong", true)
6260 .Case("weak", true)
6261 .Default(false))
6262 Tokens[I].int_data[0] = CXToken_Keyword;
6263 }
6264 continue;
6265 }
6266
6267 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6268 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6269 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6270 if (llvm::StringSwitch<bool>(II->getName())
6271 .Case("in", true)
6272 .Case("out", true)
6273 .Case("inout", true)
6274 .Case("oneway", true)
6275 .Case("bycopy", true)
6276 .Case("byref", true)
6277 .Default(false))
6278 Tokens[I].int_data[0] = CXToken_Keyword;
6279 continue;
6280 }
6281
6282 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6283 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6284 Tokens[I].int_data[0] = CXToken_Keyword;
6285 continue;
6286 }
6287 }
6288 }
6289}
6290
6291extern "C" {
6292
6293void clang_annotateTokens(CXTranslationUnit TU,
6294 CXToken *Tokens, unsigned NumTokens,
6295 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006296 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006297 LOG_BAD_TU(TU);
6298 return;
6299 }
6300 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006301 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006302 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006303 }
6304
6305 LOG_FUNC_SECTION {
6306 *Log << TU << ' ';
6307 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6308 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6309 *Log << clang_getRange(bloc, eloc);
6310 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
6312 // Any token we don't specifically annotate will have a NULL cursor.
6313 CXCursor C = clang_getNullCursor();
6314 for (unsigned I = 0; I != NumTokens; ++I)
6315 Cursors[I] = C;
6316
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006317 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006318 if (!CXXUnit)
6319 return;
6320
6321 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006322
6323 auto AnnotateTokensImpl = [=]() {
6324 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6325 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006327 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006328 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6329 }
6330}
6331
6332} // end: extern "C"
6333
6334//===----------------------------------------------------------------------===//
6335// Operations for querying linkage of a cursor.
6336//===----------------------------------------------------------------------===//
6337
6338extern "C" {
6339CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6340 if (!clang_isDeclaration(cursor.kind))
6341 return CXLinkage_Invalid;
6342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006343 const Decl *D = cxcursor::getCursorDecl(cursor);
6344 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006345 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006346 case NoLinkage:
6347 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 case InternalLinkage: return CXLinkage_Internal;
6349 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6350 case ExternalLinkage: return CXLinkage_External;
6351 };
6352
6353 return CXLinkage_Invalid;
6354}
6355} // end: extern "C"
6356
6357//===----------------------------------------------------------------------===//
6358// Operations for querying language of a cursor.
6359//===----------------------------------------------------------------------===//
6360
6361static CXLanguageKind getDeclLanguage(const Decl *D) {
6362 if (!D)
6363 return CXLanguage_C;
6364
6365 switch (D->getKind()) {
6366 default:
6367 break;
6368 case Decl::ImplicitParam:
6369 case Decl::ObjCAtDefsField:
6370 case Decl::ObjCCategory:
6371 case Decl::ObjCCategoryImpl:
6372 case Decl::ObjCCompatibleAlias:
6373 case Decl::ObjCImplementation:
6374 case Decl::ObjCInterface:
6375 case Decl::ObjCIvar:
6376 case Decl::ObjCMethod:
6377 case Decl::ObjCProperty:
6378 case Decl::ObjCPropertyImpl:
6379 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006380 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 return CXLanguage_ObjC;
6382 case Decl::CXXConstructor:
6383 case Decl::CXXConversion:
6384 case Decl::CXXDestructor:
6385 case Decl::CXXMethod:
6386 case Decl::CXXRecord:
6387 case Decl::ClassTemplate:
6388 case Decl::ClassTemplatePartialSpecialization:
6389 case Decl::ClassTemplateSpecialization:
6390 case Decl::Friend:
6391 case Decl::FriendTemplate:
6392 case Decl::FunctionTemplate:
6393 case Decl::LinkageSpec:
6394 case Decl::Namespace:
6395 case Decl::NamespaceAlias:
6396 case Decl::NonTypeTemplateParm:
6397 case Decl::StaticAssert:
6398 case Decl::TemplateTemplateParm:
6399 case Decl::TemplateTypeParm:
6400 case Decl::UnresolvedUsingTypename:
6401 case Decl::UnresolvedUsingValue:
6402 case Decl::Using:
6403 case Decl::UsingDirective:
6404 case Decl::UsingShadow:
6405 return CXLanguage_CPlusPlus;
6406 }
6407
6408 return CXLanguage_C;
6409}
6410
6411extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006412
6413static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6414 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006415 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006417 switch (D->getAvailability()) {
6418 case AR_Available:
6419 case AR_NotYetIntroduced:
6420 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006421 return getCursorAvailabilityForDecl(
6422 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423 return CXAvailability_Available;
6424
6425 case AR_Deprecated:
6426 return CXAvailability_Deprecated;
6427
6428 case AR_Unavailable:
6429 return CXAvailability_NotAvailable;
6430 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006431
6432 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006433}
6434
Guy Benyei11169dd2012-12-18 14:30:41 +00006435enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6436 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006437 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6438 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006439
6440 return CXAvailability_Available;
6441}
6442
6443static CXVersion convertVersion(VersionTuple In) {
6444 CXVersion Out = { -1, -1, -1 };
6445 if (In.empty())
6446 return Out;
6447
6448 Out.Major = In.getMajor();
6449
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006450 Optional<unsigned> Minor = In.getMinor();
6451 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 Out.Minor = *Minor;
6453 else
6454 return Out;
6455
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006456 Optional<unsigned> Subminor = In.getSubminor();
6457 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 Out.Subminor = *Subminor;
6459
6460 return Out;
6461}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006462
6463static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6464 int *always_deprecated,
6465 CXString *deprecated_message,
6466 int *always_unavailable,
6467 CXString *unavailable_message,
6468 CXPlatformAvailability *availability,
6469 int availability_size) {
6470 bool HadAvailAttr = false;
6471 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006472 for (auto A : D->attrs()) {
6473 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006474 HadAvailAttr = true;
6475 if (always_deprecated)
6476 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006477 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006478 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006479 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006480 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 continue;
6482 }
6483
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006484 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006485 HadAvailAttr = true;
6486 if (always_unavailable)
6487 *always_unavailable = 1;
6488 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006489 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006490 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6491 }
6492 continue;
6493 }
6494
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006495 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006496 HadAvailAttr = true;
6497 if (N < availability_size) {
6498 availability[N].Platform
6499 = cxstring::createDup(Avail->getPlatform()->getName());
6500 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6501 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6502 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6503 availability[N].Unavailable = Avail->getUnavailable();
6504 availability[N].Message = cxstring::createDup(Avail->getMessage());
6505 }
6506 ++N;
6507 }
6508 }
6509
6510 if (!HadAvailAttr)
6511 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6512 return getCursorPlatformAvailabilityForDecl(
6513 cast<Decl>(EnumConst->getDeclContext()),
6514 always_deprecated,
6515 deprecated_message,
6516 always_unavailable,
6517 unavailable_message,
6518 availability,
6519 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006520
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006521 return N;
6522}
6523
Guy Benyei11169dd2012-12-18 14:30:41 +00006524int clang_getCursorPlatformAvailability(CXCursor cursor,
6525 int *always_deprecated,
6526 CXString *deprecated_message,
6527 int *always_unavailable,
6528 CXString *unavailable_message,
6529 CXPlatformAvailability *availability,
6530 int availability_size) {
6531 if (always_deprecated)
6532 *always_deprecated = 0;
6533 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006534 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 if (always_unavailable)
6536 *always_unavailable = 0;
6537 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006538 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006539
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 if (!clang_isDeclaration(cursor.kind))
6541 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006542
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006543 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 if (!D)
6545 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006546
6547 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6548 deprecated_message,
6549 always_unavailable,
6550 unavailable_message,
6551 availability,
6552 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006553}
6554
6555void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6556 clang_disposeString(availability->Platform);
6557 clang_disposeString(availability->Message);
6558}
6559
6560CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6561 if (clang_isDeclaration(cursor.kind))
6562 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6563
6564 return CXLanguage_Invalid;
6565}
6566
6567 /// \brief If the given cursor is the "templated" declaration
6568 /// descibing a class or function template, return the class or
6569 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006570static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006572 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006574 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6576 return FunTmpl;
6577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006578 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6580 return ClassTmpl;
6581
6582 return D;
6583}
6584
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006585
6586enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6587 StorageClass sc = SC_None;
6588 const Decl *D = getCursorDecl(C);
6589 if (D) {
6590 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6591 sc = FD->getStorageClass();
6592 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6593 sc = VD->getStorageClass();
6594 } else {
6595 return CX_SC_Invalid;
6596 }
6597 } else {
6598 return CX_SC_Invalid;
6599 }
6600 switch (sc) {
6601 case SC_None:
6602 return CX_SC_None;
6603 case SC_Extern:
6604 return CX_SC_Extern;
6605 case SC_Static:
6606 return CX_SC_Static;
6607 case SC_PrivateExtern:
6608 return CX_SC_PrivateExtern;
6609 case SC_OpenCLWorkGroupLocal:
6610 return CX_SC_OpenCLWorkGroupLocal;
6611 case SC_Auto:
6612 return CX_SC_Auto;
6613 case SC_Register:
6614 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006615 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006616 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006617}
6618
Guy Benyei11169dd2012-12-18 14:30:41 +00006619CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6620 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006621 if (const Decl *D = getCursorDecl(cursor)) {
6622 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 if (!DC)
6624 return clang_getNullCursor();
6625
6626 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6627 getCursorTU(cursor));
6628 }
6629 }
6630
6631 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006632 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 return MakeCXCursor(D, getCursorTU(cursor));
6634 }
6635
6636 return clang_getNullCursor();
6637}
6638
6639CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6640 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006641 if (const Decl *D = getCursorDecl(cursor)) {
6642 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006643 if (!DC)
6644 return clang_getNullCursor();
6645
6646 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6647 getCursorTU(cursor));
6648 }
6649 }
6650
6651 // FIXME: Note that we can't easily compute the lexical context of a
6652 // statement or expression, so we return nothing.
6653 return clang_getNullCursor();
6654}
6655
6656CXFile clang_getIncludedFile(CXCursor cursor) {
6657 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006658 return nullptr;
6659
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006660 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006661 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006662}
6663
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006664unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6665 if (C.kind != CXCursor_ObjCPropertyDecl)
6666 return CXObjCPropertyAttr_noattr;
6667
6668 unsigned Result = CXObjCPropertyAttr_noattr;
6669 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6670 ObjCPropertyDecl::PropertyAttributeKind Attr =
6671 PD->getPropertyAttributesAsWritten();
6672
6673#define SET_CXOBJCPROP_ATTR(A) \
6674 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6675 Result |= CXObjCPropertyAttr_##A
6676 SET_CXOBJCPROP_ATTR(readonly);
6677 SET_CXOBJCPROP_ATTR(getter);
6678 SET_CXOBJCPROP_ATTR(assign);
6679 SET_CXOBJCPROP_ATTR(readwrite);
6680 SET_CXOBJCPROP_ATTR(retain);
6681 SET_CXOBJCPROP_ATTR(copy);
6682 SET_CXOBJCPROP_ATTR(nonatomic);
6683 SET_CXOBJCPROP_ATTR(setter);
6684 SET_CXOBJCPROP_ATTR(atomic);
6685 SET_CXOBJCPROP_ATTR(weak);
6686 SET_CXOBJCPROP_ATTR(strong);
6687 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6688#undef SET_CXOBJCPROP_ATTR
6689
6690 return Result;
6691}
6692
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006693unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6694 if (!clang_isDeclaration(C.kind))
6695 return CXObjCDeclQualifier_None;
6696
6697 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6698 const Decl *D = getCursorDecl(C);
6699 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6700 QT = MD->getObjCDeclQualifier();
6701 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6702 QT = PD->getObjCDeclQualifier();
6703 if (QT == Decl::OBJC_TQ_None)
6704 return CXObjCDeclQualifier_None;
6705
6706 unsigned Result = CXObjCDeclQualifier_None;
6707 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6708 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6709 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6710 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6711 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6712 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6713
6714 return Result;
6715}
6716
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006717unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6718 if (!clang_isDeclaration(C.kind))
6719 return 0;
6720
6721 const Decl *D = getCursorDecl(C);
6722 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6723 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6724 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6725 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6726
6727 return 0;
6728}
6729
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006730unsigned clang_Cursor_isVariadic(CXCursor C) {
6731 if (!clang_isDeclaration(C.kind))
6732 return 0;
6733
6734 const Decl *D = getCursorDecl(C);
6735 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6736 return FD->isVariadic();
6737 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6738 return MD->isVariadic();
6739
6740 return 0;
6741}
6742
Guy Benyei11169dd2012-12-18 14:30:41 +00006743CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6744 if (!clang_isDeclaration(C.kind))
6745 return clang_getNullRange();
6746
6747 const Decl *D = getCursorDecl(C);
6748 ASTContext &Context = getCursorContext(C);
6749 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6750 if (!RC)
6751 return clang_getNullRange();
6752
6753 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6754}
6755
6756CXString clang_Cursor_getRawCommentText(CXCursor C) {
6757 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006758 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006759
6760 const Decl *D = getCursorDecl(C);
6761 ASTContext &Context = getCursorContext(C);
6762 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6763 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6764 StringRef();
6765
6766 // Don't duplicate the string because RawText points directly into source
6767 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006768 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006769}
6770
6771CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6772 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006773 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006774
6775 const Decl *D = getCursorDecl(C);
6776 const ASTContext &Context = getCursorContext(C);
6777 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6778
6779 if (RC) {
6780 StringRef BriefText = RC->getBriefText(Context);
6781
6782 // Don't duplicate the string because RawComment ensures that this memory
6783 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006784 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 }
6786
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006787 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006788}
6789
Guy Benyei11169dd2012-12-18 14:30:41 +00006790CXModule clang_Cursor_getModule(CXCursor C) {
6791 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006792 if (const ImportDecl *ImportD =
6793 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006794 return ImportD->getImportedModule();
6795 }
6796
Craig Topper69186e72014-06-08 08:38:04 +00006797 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006798}
6799
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006800CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6801 if (isNotUsableTU(TU)) {
6802 LOG_BAD_TU(TU);
6803 return nullptr;
6804 }
6805 if (!File)
6806 return nullptr;
6807 FileEntry *FE = static_cast<FileEntry *>(File);
6808
6809 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6810 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6811 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6812
Richard Smithfeb54b62014-10-23 02:01:19 +00006813 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006814}
6815
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006816CXFile clang_Module_getASTFile(CXModule CXMod) {
6817 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006818 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006819 Module *Mod = static_cast<Module*>(CXMod);
6820 return const_cast<FileEntry *>(Mod->getASTFile());
6821}
6822
Guy Benyei11169dd2012-12-18 14:30:41 +00006823CXModule clang_Module_getParent(CXModule CXMod) {
6824 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006825 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006826 Module *Mod = static_cast<Module*>(CXMod);
6827 return Mod->Parent;
6828}
6829
6830CXString clang_Module_getName(CXModule CXMod) {
6831 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006832 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006834 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006835}
6836
6837CXString clang_Module_getFullName(CXModule CXMod) {
6838 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006839 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006841 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006842}
6843
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006844int clang_Module_isSystem(CXModule CXMod) {
6845 if (!CXMod)
6846 return 0;
6847 Module *Mod = static_cast<Module*>(CXMod);
6848 return Mod->IsSystem;
6849}
6850
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006851unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6852 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006853 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006854 LOG_BAD_TU(TU);
6855 return 0;
6856 }
6857 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 return 0;
6859 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006860 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6861 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6862 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006863}
6864
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006865CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6866 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006867 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006868 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006869 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006870 }
6871 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006873 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006874 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006875
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006876 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6877 if (Index < TopHeaders.size())
6878 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006879
Craig Topper69186e72014-06-08 08:38:04 +00006880 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006881}
6882
6883} // end: extern "C"
6884
6885//===----------------------------------------------------------------------===//
6886// C++ AST instrospection.
6887//===----------------------------------------------------------------------===//
6888
6889extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006890unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6891 if (!clang_isDeclaration(C.kind))
6892 return 0;
6893
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006894 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006895 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006896 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006897 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6898}
6899
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006900unsigned clang_CXXMethod_isConst(CXCursor C) {
6901 if (!clang_isDeclaration(C.kind))
6902 return 0;
6903
6904 const Decl *D = cxcursor::getCursorDecl(C);
6905 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006906 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006907 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6908}
6909
Guy Benyei11169dd2012-12-18 14:30:41 +00006910unsigned clang_CXXMethod_isStatic(CXCursor C) {
6911 if (!clang_isDeclaration(C.kind))
6912 return 0;
6913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006914 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006915 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006916 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 return (Method && Method->isStatic()) ? 1 : 0;
6918}
6919
6920unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6921 if (!clang_isDeclaration(C.kind))
6922 return 0;
6923
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006924 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006925 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006926 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006927 return (Method && Method->isVirtual()) ? 1 : 0;
6928}
6929} // end: extern "C"
6930
6931//===----------------------------------------------------------------------===//
6932// Attribute introspection.
6933//===----------------------------------------------------------------------===//
6934
6935extern "C" {
6936CXType clang_getIBOutletCollectionType(CXCursor C) {
6937 if (C.kind != CXCursor_IBOutletCollectionAttr)
6938 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6939
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006940 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6942
6943 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6944}
6945} // end: extern "C"
6946
6947//===----------------------------------------------------------------------===//
6948// Inspecting memory usage.
6949//===----------------------------------------------------------------------===//
6950
6951typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6952
6953static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6954 enum CXTUResourceUsageKind k,
6955 unsigned long amount) {
6956 CXTUResourceUsageEntry entry = { k, amount };
6957 entries.push_back(entry);
6958}
6959
6960extern "C" {
6961
6962const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6963 const char *str = "";
6964 switch (kind) {
6965 case CXTUResourceUsage_AST:
6966 str = "ASTContext: expressions, declarations, and types";
6967 break;
6968 case CXTUResourceUsage_Identifiers:
6969 str = "ASTContext: identifiers";
6970 break;
6971 case CXTUResourceUsage_Selectors:
6972 str = "ASTContext: selectors";
6973 break;
6974 case CXTUResourceUsage_GlobalCompletionResults:
6975 str = "Code completion: cached global results";
6976 break;
6977 case CXTUResourceUsage_SourceManagerContentCache:
6978 str = "SourceManager: content cache allocator";
6979 break;
6980 case CXTUResourceUsage_AST_SideTables:
6981 str = "ASTContext: side tables";
6982 break;
6983 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6984 str = "SourceManager: malloc'ed memory buffers";
6985 break;
6986 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6987 str = "SourceManager: mmap'ed memory buffers";
6988 break;
6989 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6990 str = "ExternalASTSource: malloc'ed memory buffers";
6991 break;
6992 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6993 str = "ExternalASTSource: mmap'ed memory buffers";
6994 break;
6995 case CXTUResourceUsage_Preprocessor:
6996 str = "Preprocessor: malloc'ed memory";
6997 break;
6998 case CXTUResourceUsage_PreprocessingRecord:
6999 str = "Preprocessor: PreprocessingRecord";
7000 break;
7001 case CXTUResourceUsage_SourceManager_DataStructures:
7002 str = "SourceManager: data structures and tables";
7003 break;
7004 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7005 str = "Preprocessor: header search tables";
7006 break;
7007 }
7008 return str;
7009}
7010
7011CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007012 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007013 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007014 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 return usage;
7016 }
7017
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007018 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007019 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007020 ASTContext &astContext = astUnit->getASTContext();
7021
7022 // How much memory is used by AST nodes and types?
7023 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7024 (unsigned long) astContext.getASTAllocatedMemory());
7025
7026 // How much memory is used by identifiers?
7027 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7028 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7029
7030 // How much memory is used for selectors?
7031 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7032 (unsigned long) astContext.Selectors.getTotalMemory());
7033
7034 // How much memory is used by ASTContext's side tables?
7035 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7036 (unsigned long) astContext.getSideTableAllocatedMemory());
7037
7038 // How much memory is used for caching global code completion results?
7039 unsigned long completionBytes = 0;
7040 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007041 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 completionBytes = completionAllocator->getTotalMemory();
7043 }
7044 createCXTUResourceUsageEntry(*entries,
7045 CXTUResourceUsage_GlobalCompletionResults,
7046 completionBytes);
7047
7048 // How much memory is being used by SourceManager's content cache?
7049 createCXTUResourceUsageEntry(*entries,
7050 CXTUResourceUsage_SourceManagerContentCache,
7051 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7052
7053 // How much memory is being used by the MemoryBuffer's in SourceManager?
7054 const SourceManager::MemoryBufferSizes &srcBufs =
7055 astUnit->getSourceManager().getMemoryBufferSizes();
7056
7057 createCXTUResourceUsageEntry(*entries,
7058 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7059 (unsigned long) srcBufs.malloc_bytes);
7060 createCXTUResourceUsageEntry(*entries,
7061 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7062 (unsigned long) srcBufs.mmap_bytes);
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_SourceManager_DataStructures,
7065 (unsigned long) astContext.getSourceManager()
7066 .getDataStructureSizes());
7067
7068 // How much memory is being used by the ExternalASTSource?
7069 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7070 const ExternalASTSource::MemoryBufferSizes &sizes =
7071 esrc->getMemoryBufferSizes();
7072
7073 createCXTUResourceUsageEntry(*entries,
7074 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7075 (unsigned long) sizes.malloc_bytes);
7076 createCXTUResourceUsageEntry(*entries,
7077 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7078 (unsigned long) sizes.mmap_bytes);
7079 }
7080
7081 // How much memory is being used by the Preprocessor?
7082 Preprocessor &pp = astUnit->getPreprocessor();
7083 createCXTUResourceUsageEntry(*entries,
7084 CXTUResourceUsage_Preprocessor,
7085 pp.getTotalMemory());
7086
7087 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7088 createCXTUResourceUsageEntry(*entries,
7089 CXTUResourceUsage_PreprocessingRecord,
7090 pRec->getTotalMemory());
7091 }
7092
7093 createCXTUResourceUsageEntry(*entries,
7094 CXTUResourceUsage_Preprocessor_HeaderSearch,
7095 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007096
Guy Benyei11169dd2012-12-18 14:30:41 +00007097 CXTUResourceUsage usage = { (void*) entries.get(),
7098 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007099 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007100 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 return usage;
7102}
7103
7104void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7105 if (usage.data)
7106 delete (MemUsageEntries*) usage.data;
7107}
7108
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007109CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7110 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007111 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007112 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007113
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007114 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007115 LOG_BAD_TU(TU);
7116 return skipped;
7117 }
7118
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007119 if (!file)
7120 return skipped;
7121
7122 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7123 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7124 if (!ppRec)
7125 return skipped;
7126
7127 ASTContext &Ctx = astUnit->getASTContext();
7128 SourceManager &sm = Ctx.getSourceManager();
7129 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7130 FileID wantedFileID = sm.translateFile(fileEntry);
7131
7132 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7133 std::vector<SourceRange> wantedRanges;
7134 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7135 i != ei; ++i) {
7136 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7137 wantedRanges.push_back(*i);
7138 }
7139
7140 skipped->count = wantedRanges.size();
7141 skipped->ranges = new CXSourceRange[skipped->count];
7142 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7143 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7144
7145 return skipped;
7146}
7147
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007148void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7149 if (ranges) {
7150 delete[] ranges->ranges;
7151 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007152 }
7153}
7154
Guy Benyei11169dd2012-12-18 14:30:41 +00007155} // end extern "C"
7156
7157void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7158 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7159 for (unsigned I = 0; I != Usage.numEntries; ++I)
7160 fprintf(stderr, " %s: %lu\n",
7161 clang_getTUResourceUsageName(Usage.entries[I].kind),
7162 Usage.entries[I].amount);
7163
7164 clang_disposeCXTUResourceUsage(Usage);
7165}
7166
7167//===----------------------------------------------------------------------===//
7168// Misc. utility functions.
7169//===----------------------------------------------------------------------===//
7170
7171/// Default to using an 8 MB stack size on "safety" threads.
7172static unsigned SafetyStackThreadSize = 8 << 20;
7173
7174namespace clang {
7175
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007176bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007177 unsigned Size) {
7178 if (!Size)
7179 Size = GetSafetyThreadStackSize();
7180 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007181 return CRC.RunSafelyOnThread(Fn, Size);
7182 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007183}
7184
7185unsigned GetSafetyThreadStackSize() {
7186 return SafetyStackThreadSize;
7187}
7188
7189void SetSafetyThreadStackSize(unsigned Value) {
7190 SafetyStackThreadSize = Value;
7191}
7192
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007193}
Guy Benyei11169dd2012-12-18 14:30:41 +00007194
7195void clang::setThreadBackgroundPriority() {
7196 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7197 return;
7198
Alp Toker1a86ad22014-07-06 06:24:00 +00007199#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007200 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7201#endif
7202}
7203
7204void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7205 if (!Unit)
7206 return;
7207
7208 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7209 DEnd = Unit->stored_diag_end();
7210 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007211 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007212 CXString Msg = clang_formatDiagnostic(&Diag,
7213 clang_defaultDiagnosticDisplayOptions());
7214 fprintf(stderr, "%s\n", clang_getCString(Msg));
7215 clang_disposeString(Msg);
7216 }
7217#ifdef LLVM_ON_WIN32
7218 // On Windows, force a flush, since there may be multiple copies of
7219 // stderr and stdout in the file system, all with different buffers
7220 // but writing to the same device.
7221 fflush(stderr);
7222#endif
7223}
7224
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007225MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7226 SourceLocation MacroDefLoc,
7227 CXTranslationUnit TU){
7228 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007229 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007231 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007232
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007233 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007234 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007235 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007236 if (MD) {
7237 for (MacroDirective::DefInfo
7238 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7239 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7240 return Def.getMacroInfo();
7241 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007242 }
7243
Craig Topper69186e72014-06-08 08:38:04 +00007244 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007245}
7246
Richard Smith66a81862015-05-04 02:25:31 +00007247const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007248 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007249 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007250 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251 const IdentifierInfo *II = MacroDef->getName();
7252 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007253 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007254
7255 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7256}
7257
Richard Smith66a81862015-05-04 02:25:31 +00007258MacroDefinitionRecord *
7259cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7260 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007262 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007263 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007264 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007265
7266 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007267 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7269 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007270 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007271
7272 // Check that the token is inside the definition and not its argument list.
7273 SourceManager &SM = Unit->getSourceManager();
7274 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007275 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007276 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007277 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278
7279 Preprocessor &PP = Unit->getPreprocessor();
7280 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7281 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283
Alp Toker2d57cea2014-05-17 04:53:25 +00007284 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007285 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007286 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007287
7288 // Check that the identifier is not one of the macro arguments.
7289 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007290 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007291
Richard Smith20e883e2015-04-29 23:20:19 +00007292 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007293 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007294 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007295
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007296 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007297}
7298
Richard Smith66a81862015-05-04 02:25:31 +00007299MacroDefinitionRecord *
7300cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7301 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007302 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007303 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007304
7305 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007306 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007307 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007308 Preprocessor &PP = Unit->getPreprocessor();
7309 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007310 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007311 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7312 Token Tok;
7313 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007314 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007315
7316 return checkForMacroInMacroDefinition(MI, Tok, TU);
7317}
7318
Guy Benyei11169dd2012-12-18 14:30:41 +00007319extern "C" {
7320
7321CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007322 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007323}
7324
7325} // end: extern "C"
7326
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007327Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7328 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007329 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007331 if (Unit->isMainFileAST())
7332 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007333 return *this;
7334 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007335 } else {
7336 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007337 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007338 return *this;
7339}
7340
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007341Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7342 *this << FE->getName();
7343 return *this;
7344}
7345
7346Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7347 CXString cursorName = clang_getCursorDisplayName(cursor);
7348 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7349 clang_disposeString(cursorName);
7350 return *this;
7351}
7352
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007353Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7354 CXFile File;
7355 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007356 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007357 CXString FileName = clang_getFileName(File);
7358 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7359 clang_disposeString(FileName);
7360 return *this;
7361}
7362
7363Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7364 CXSourceLocation BLoc = clang_getRangeStart(range);
7365 CXSourceLocation ELoc = clang_getRangeEnd(range);
7366
7367 CXFile BFile;
7368 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007369 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007370
7371 CXFile EFile;
7372 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007373 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007374
7375 CXString BFileName = clang_getFileName(BFile);
7376 if (BFile == EFile) {
7377 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7378 BLine, BColumn, ELine, EColumn);
7379 } else {
7380 CXString EFileName = clang_getFileName(EFile);
7381 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7382 BLine, BColumn)
7383 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7384 ELine, EColumn);
7385 clang_disposeString(EFileName);
7386 }
7387 clang_disposeString(BFileName);
7388 return *this;
7389}
7390
7391Logger &cxindex::Logger::operator<<(CXString Str) {
7392 *this << clang_getCString(Str);
7393 return *this;
7394}
7395
7396Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7397 LogOS << Fmt;
7398 return *this;
7399}
7400
Chandler Carruth37ad2582014-06-27 15:14:39 +00007401static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7402
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007403cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007404 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007405
7406 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7407
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007408 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007409 OS << "[libclang:" << Name << ':';
7410
Alp Toker1a86ad22014-07-06 06:24:00 +00007411#ifdef USE_DARWIN_THREADS
7412 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007413 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7414 OS << tid << ':';
7415#endif
7416
7417 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7418 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007419 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007420
7421 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007422 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007423 OS << "--------------------------------------------------\n";
7424 }
7425}