blob: e34ee346fc081dc518576bc8d9d86659e87ad821 [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) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001526 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001527}
1528
1529bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1530 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1531 return true;
1532
Douglas Gregore9d95f12015-07-07 03:57:35 +00001533 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1534 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1535 return true;
1536 }
1537
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1539 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1540 TU)))
1541 return true;
1542 }
1543
1544 return false;
1545}
1546
1547bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1548 return Visit(TL.getPointeeLoc());
1549}
1550
1551bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1552 return Visit(TL.getInnerLoc());
1553}
1554
1555bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1556 return Visit(TL.getPointeeLoc());
1557}
1558
1559bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1560 return Visit(TL.getPointeeLoc());
1561}
1562
1563bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1564 return Visit(TL.getPointeeLoc());
1565}
1566
1567bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1568 return Visit(TL.getPointeeLoc());
1569}
1570
1571bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1572 return Visit(TL.getPointeeLoc());
1573}
1574
1575bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1576 return Visit(TL.getModifiedLoc());
1577}
1578
1579bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1580 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001581 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001582 return true;
1583
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001584 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1585 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001586 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1593 if (Visit(TL.getElementLoc()))
1594 return true;
1595
1596 if (Expr *Size = TL.getSizeExpr())
1597 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1598
1599 return false;
1600}
1601
Reid Kleckner8a365022013-06-24 17:51:48 +00001602bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1603 return Visit(TL.getOriginalLoc());
1604}
1605
Reid Kleckner0503a872013-12-05 01:23:43 +00001606bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1607 return Visit(TL.getOriginalLoc());
1608}
1609
Guy Benyei11169dd2012-12-18 14:30:41 +00001610bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1611 TemplateSpecializationTypeLoc TL) {
1612 // Visit the template name.
1613 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1614 TL.getTemplateNameLoc()))
1615 return true;
1616
1617 // Visit the template arguments.
1618 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1619 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1620 return true;
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1626 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1627}
1628
1629bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1630 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1631 return Visit(TSInfo->getTypeLoc());
1632
1633 return false;
1634}
1635
1636bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001644 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001645}
1646
1647bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1648 DependentTemplateSpecializationTypeLoc TL) {
1649 // Visit the nested-name-specifier, if there is one.
1650 if (TL.getQualifierLoc() &&
1651 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1652 return true;
1653
1654 // Visit the template arguments.
1655 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1656 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1657 return true;
1658
1659 return false;
1660}
1661
1662bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1663 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1664 return true;
1665
1666 return Visit(TL.getNamedTypeLoc());
1667}
1668
1669bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1670 return Visit(TL.getPatternLoc());
1671}
1672
1673bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1674 if (Expr *E = TL.getUnderlyingExpr())
1675 return Visit(MakeCXCursor(E, StmtParent, TU));
1676
1677 return false;
1678}
1679
1680bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1681 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1682}
1683
1684bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1685 return Visit(TL.getValueLoc());
1686}
1687
1688#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1689bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1690 return Visit##PARENT##Loc(TL); \
1691}
1692
1693DEFAULT_TYPELOC_IMPL(Complex, Type)
1694DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1695DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1696DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1697DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1698DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1699DEFAULT_TYPELOC_IMPL(Vector, Type)
1700DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1701DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1702DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1703DEFAULT_TYPELOC_IMPL(Record, TagType)
1704DEFAULT_TYPELOC_IMPL(Enum, TagType)
1705DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1706DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1707DEFAULT_TYPELOC_IMPL(Auto, Type)
1708
1709bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1710 // Visit the nested-name-specifier, if present.
1711 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1712 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1713 return true;
1714
1715 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001716 for (const auto &I : D->bases()) {
1717 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 return true;
1719 }
1720 }
1721
1722 return VisitTagDecl(D);
1723}
1724
1725bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001726 for (const auto *I : D->attrs())
1727 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001728 return true;
1729
1730 return false;
1731}
1732
1733//===----------------------------------------------------------------------===//
1734// Data-recursive visitor methods.
1735//===----------------------------------------------------------------------===//
1736
1737namespace {
1738#define DEF_JOB(NAME, DATA, KIND)\
1739class NAME : public VisitorJob {\
1740public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001741 NAME(const DATA *d, CXCursor parent) : \
1742 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001745};
1746
1747DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1748DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1749DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1750DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1751DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1752 ExplicitTemplateArgsVisitKind)
1753DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1754DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1755DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1756#undef DEF_JOB
1757
1758class DeclVisit : public VisitorJob {
1759public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001760 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001762 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001763 static bool classof(const VisitorJob *VJ) {
1764 return VJ->getKind() == DeclVisitKind;
1765 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001767 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001768};
1769class TypeLocVisit : public VisitorJob {
1770public:
1771 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1772 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1773 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1774
1775 static bool classof(const VisitorJob *VJ) {
1776 return VJ->getKind() == TypeLocVisitKind;
1777 }
1778
1779 TypeLoc get() const {
1780 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 }
1783};
1784
1785class LabelRefVisit : public VisitorJob {
1786public:
1787 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1788 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1789 labelLoc.getPtrEncoding()) {}
1790
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const LabelDecl *get() const {
1795 return static_cast<const LabelDecl *>(data[0]);
1796 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromPtrEncoding(data[1]); }
1799};
1800
1801class NestedNameSpecifierLocVisit : public VisitorJob {
1802public:
1803 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1804 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1805 Qualifier.getNestedNameSpecifier(),
1806 Qualifier.getOpaqueData()) { }
1807
1808 static bool classof(const VisitorJob *VJ) {
1809 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1810 }
1811
1812 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 return NestedNameSpecifierLoc(
1814 const_cast<NestedNameSpecifier *>(
1815 static_cast<const NestedNameSpecifier *>(data[0])),
1816 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001817 }
1818};
1819
1820class DeclarationNameInfoVisit : public VisitorJob {
1821public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001822 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001823 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 static bool classof(const VisitorJob *VJ) {
1825 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1826 }
1827 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001828 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001829 switch (S->getStmtClass()) {
1830 default:
1831 llvm_unreachable("Unhandled Stmt");
1832 case clang::Stmt::MSDependentExistsStmtClass:
1833 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1834 case Stmt::CXXDependentScopeMemberExprClass:
1835 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1836 case Stmt::DependentScopeDeclRefExprClass:
1837 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001838 case Stmt::OMPCriticalDirectiveClass:
1839 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001840 }
1841 }
1842};
1843class MemberRefVisit : public VisitorJob {
1844public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1847 L.getPtrEncoding()) {}
1848 static bool classof(const VisitorJob *VJ) {
1849 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1850 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 const FieldDecl *get() const {
1852 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 }
1854 SourceLocation getLoc() const {
1855 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1856 }
1857};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001859 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 VisitorWorkList &WL;
1861 CXCursor Parent;
1862public:
1863 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1864 : WL(wl), Parent(parent) {}
1865
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1867 void VisitBlockExpr(const BlockExpr *B);
1868 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1869 void VisitCompoundStmt(const CompoundStmt *S);
1870 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1871 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1872 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1873 void VisitCXXNewExpr(const CXXNewExpr *E);
1874 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1875 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1876 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1877 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1878 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1879 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1880 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1881 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001882 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void VisitDeclRefExpr(const DeclRefExpr *D);
1884 void VisitDeclStmt(const DeclStmt *S);
1885 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1886 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1887 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1888 void VisitForStmt(const ForStmt *FS);
1889 void VisitGotoStmt(const GotoStmt *GS);
1890 void VisitIfStmt(const IfStmt *If);
1891 void VisitInitListExpr(const InitListExpr *IE);
1892 void VisitMemberExpr(const MemberExpr *M);
1893 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1894 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1895 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1896 void VisitOverloadExpr(const OverloadExpr *E);
1897 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1898 void VisitStmt(const Stmt *S);
1899 void VisitSwitchStmt(const SwitchStmt *S);
1900 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1902 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1903 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1904 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1905 void VisitVAArgExpr(const VAArgExpr *E);
1906 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1907 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1908 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1909 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001910 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001911 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001912 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001913 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001914 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001915 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001916 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001917 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001918 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001919 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001920 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001921 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001922 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001923 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001924 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001925 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001926 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001927 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001928 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001929 void
1930 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001931 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001932 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001933 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001934 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001935 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001936 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001937 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001938
Guy Benyei11169dd2012-12-18 14:30:41 +00001939private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001940 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001941 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1942 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001943 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1944 void AddStmt(const Stmt *S);
1945 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001946 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001949};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001950} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001951
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001953 // 'S' should always be non-null, since it comes from the
1954 // statement we are visiting.
1955 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1956}
1957
1958void
1959EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1960 if (Qualifier)
1961 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1962}
1963
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 if (S)
1966 WL.push_back(StmtVisit(S, Parent));
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 if (D)
1970 WL.push_back(DeclVisit(D, Parent, isFirst));
1971}
1972void EnqueueVisitor::
1973 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1974 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 if (D)
1979 WL.push_back(MemberRefVisit(D, L, Parent));
1980}
1981void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1982 if (TI)
1983 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1984 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001987 for (const Stmt *SubStmt : S->children()) {
1988 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 }
1990 if (size == WL.size())
1991 return;
1992 // Now reverse the entries we just added. This will match the DFS
1993 // ordering performed by the worklist.
1994 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1995 std::reverse(I, E);
1996}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001997namespace {
1998class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1999 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002000 /// \brief Process clauses with list of variables.
2001 template <typename T>
2002 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003public:
2004 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2005#define OPENMP_CLAUSE(Name, Class) \
2006 void Visit##Class(const Class *C);
2007#include "clang/Basic/OpenMPKinds.def"
2008};
2009
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002010void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2011 Visitor->AddStmt(C->getCondition());
2012}
2013
Alexey Bataev3778b602014-07-17 07:32:53 +00002014void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2015 Visitor->AddStmt(C->getCondition());
2016}
2017
Alexey Bataev568a8332014-03-06 06:15:19 +00002018void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2019 Visitor->AddStmt(C->getNumThreads());
2020}
2021
Alexey Bataev62c87d22014-03-21 04:51:18 +00002022void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2023 Visitor->AddStmt(C->getSafelen());
2024}
2025
Alexey Bataev66b15b52015-08-21 11:14:16 +00002026void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2027 Visitor->AddStmt(C->getSimdlen());
2028}
2029
Alexander Musman8bd31e62014-05-27 15:12:19 +00002030void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2031 Visitor->AddStmt(C->getNumForLoops());
2032}
2033
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002034void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002035
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002036void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2037
Alexey Bataev56dafe82014-06-20 07:16:17 +00002038void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2039 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002040 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002041}
2042
Alexey Bataev10e775f2015-07-30 11:36:16 +00002043void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2044 Visitor->AddStmt(C->getNumForLoops());
2045}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002046
Alexey Bataev236070f2014-06-20 11:19:47 +00002047void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2048
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002049void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2050
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002051void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2052
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002053void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2054
Alexey Bataevdea47612014-07-23 07:46:59 +00002055void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2056
Alexey Bataev67a4f222014-07-23 10:25:33 +00002057void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2058
Alexey Bataev459dec02014-07-24 06:46:57 +00002059void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2060
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002061void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2062
Alexey Bataev346265e2015-09-25 10:37:12 +00002063void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2064
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002065void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2066
Michael Wonge710d542015-08-07 16:16:36 +00002067void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2068 Visitor->AddStmt(C->getDevice());
2069}
2070
Alexey Bataev756c1962013-09-24 03:17:45 +00002071template<typename T>
2072void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002073 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002074 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002075 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002076}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002077
2078void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002079 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002080 for (const auto *E : C->private_copies()) {
2081 Visitor->AddStmt(E);
2082 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002083}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002084void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2085 const OMPFirstprivateClause *C) {
2086 VisitOMPClauseList(C);
2087}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002088void OMPClauseEnqueue::VisitOMPLastprivateClause(
2089 const OMPLastprivateClause *C) {
2090 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002091 for (auto *E : C->private_copies()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->source_exprs()) {
2095 Visitor->AddStmt(E);
2096 }
2097 for (auto *E : C->destination_exprs()) {
2098 Visitor->AddStmt(E);
2099 }
2100 for (auto *E : C->assignment_ops()) {
2101 Visitor->AddStmt(E);
2102 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002103}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002104void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002105 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002106}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002107void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2108 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002109 for (auto *E : C->lhs_exprs()) {
2110 Visitor->AddStmt(E);
2111 }
2112 for (auto *E : C->rhs_exprs()) {
2113 Visitor->AddStmt(E);
2114 }
2115 for (auto *E : C->reduction_ops()) {
2116 Visitor->AddStmt(E);
2117 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002118}
Alexander Musman8dba6642014-04-22 13:09:42 +00002119void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2120 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002121 for (const auto *E : C->privates()) {
2122 Visitor->AddStmt(E);
2123 }
Alexander Musman3276a272015-03-21 10:12:56 +00002124 for (const auto *E : C->inits()) {
2125 Visitor->AddStmt(E);
2126 }
2127 for (const auto *E : C->updates()) {
2128 Visitor->AddStmt(E);
2129 }
2130 for (const auto *E : C->finals()) {
2131 Visitor->AddStmt(E);
2132 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002133 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002134 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002135}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002136void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2137 VisitOMPClauseList(C);
2138 Visitor->AddStmt(C->getAlignment());
2139}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002140void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2141 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002142 for (auto *E : C->source_exprs()) {
2143 Visitor->AddStmt(E);
2144 }
2145 for (auto *E : C->destination_exprs()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (auto *E : C->assignment_ops()) {
2149 Visitor->AddStmt(E);
2150 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002151}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002152void
2153OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2154 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002155 for (auto *E : C->source_exprs()) {
2156 Visitor->AddStmt(E);
2157 }
2158 for (auto *E : C->destination_exprs()) {
2159 Visitor->AddStmt(E);
2160 }
2161 for (auto *E : C->assignment_ops()) {
2162 Visitor->AddStmt(E);
2163 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002164}
Alexey Bataev6125da92014-07-21 11:26:11 +00002165void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2166 VisitOMPClauseList(C);
2167}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002168void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2169 VisitOMPClauseList(C);
2170}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002171}
Alexey Bataev756c1962013-09-24 03:17:45 +00002172
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002173void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2174 unsigned size = WL.size();
2175 OMPClauseEnqueue Visitor(this);
2176 Visitor.Visit(S);
2177 if (size == WL.size())
2178 return;
2179 // Now reverse the entries we just added. This will match the DFS
2180 // ordering performed by the worklist.
2181 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2182 std::reverse(I, E);
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 AddDecl(B->getBlockDecl());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 EnqueueChildren(E);
2192 AddTypeLoc(E->getTypeSourceInfo());
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002195 for (auto &I : llvm::reverse(S->body()))
2196 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002197}
2198void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddStmt(S->getSubStmt());
2201 AddDeclarationNameInfo(S);
2202 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2203 AddNestedNameSpecifierLoc(QualifierLoc);
2204}
2205
2206void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2209 AddDeclarationNameInfo(E);
2210 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2211 AddNestedNameSpecifierLoc(QualifierLoc);
2212 if (!E->isImplicitAccess())
2213 AddStmt(E->getBase());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 // Enqueue the initializer , if any.
2217 AddStmt(E->getInitializer());
2218 // Enqueue the array size, if any.
2219 AddStmt(E->getArraySize());
2220 // Enqueue the allocated type.
2221 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2222 // Enqueue the placement arguments.
2223 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2224 AddStmt(E->getPlacementArg(I-1));
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2228 AddStmt(CE->getArg(I-1));
2229 AddStmt(CE->getCallee());
2230 AddStmt(CE->getArg(0));
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2233 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 // Visit the name of the type being destroyed.
2235 AddTypeLoc(E->getDestroyedTypeInfo());
2236 // Visit the scope type that looks disturbingly like the nested-name-specifier
2237 // but isn't.
2238 AddTypeLoc(E->getScopeTypeInfo());
2239 // Visit the nested-name-specifier.
2240 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2241 AddNestedNameSpecifierLoc(QualifierLoc);
2242 // Visit base expression.
2243 AddStmt(E->getBase());
2244}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2246 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 AddTypeLoc(E->getTypeSourceInfo());
2248}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2250 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(E);
2252 AddTypeLoc(E->getTypeSourceInfo());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 EnqueueChildren(E);
2256 if (E->isTypeOperand())
2257 AddTypeLoc(E->getTypeOperandSourceInfo());
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2261 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 EnqueueChildren(E);
2263 AddTypeLoc(E->getTypeSourceInfo());
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(E);
2267 if (E->isTypeOperand())
2268 AddTypeLoc(E->getTypeOperandSourceInfo());
2269}
2270
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(S);
2273 AddDecl(S->getExceptionDecl());
2274}
2275
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002276void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002277 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002278 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002279 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002280}
2281
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 if (DR->hasExplicitTemplateArgs()) {
2284 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2285 }
2286 WL.push_back(DeclRefExprParts(DR, Parent));
2287}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2289 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2291 AddDeclarationNameInfo(E);
2292 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 unsigned size = WL.size();
2296 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002297 for (const auto *D : S->decls()) {
2298 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 isFirst = false;
2300 }
2301 if (size == WL.size())
2302 return;
2303 // Now reverse the entries we just added. This will match the DFS
2304 // ordering performed by the worklist.
2305 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2306 std::reverse(I, E);
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 D = E->designators_rbegin(), DEnd = E->designators_rend();
2312 D != DEnd; ++D) {
2313 if (D->isFieldDesignator()) {
2314 if (FieldDecl *Field = D->getField())
2315 AddMemberRef(Field, D->getFieldLoc());
2316 continue;
2317 }
2318 if (D->isArrayDesignator()) {
2319 AddStmt(E->getArrayIndex(*D));
2320 continue;
2321 }
2322 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2323 AddStmt(E->getArrayRangeEnd(*D));
2324 AddStmt(E->getArrayRangeStart(*D));
2325 }
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 EnqueueChildren(E);
2329 AddTypeLoc(E->getTypeInfoAsWritten());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 AddStmt(FS->getBody());
2333 AddStmt(FS->getInc());
2334 AddStmt(FS->getCond());
2335 AddDecl(FS->getConditionVariable());
2336 AddStmt(FS->getInit());
2337}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 AddStmt(If->getElse());
2343 AddStmt(If->getThen());
2344 AddStmt(If->getCond());
2345 AddDecl(If->getConditionVariable());
2346}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 // We care about the syntactic form of the initializer list, only.
2349 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2350 IE = Syntactic;
2351 EnqueueChildren(IE);
2352}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 WL.push_back(MemberExprParts(M, Parent));
2355
2356 // If the base of the member access expression is an implicit 'this', don't
2357 // visit it.
2358 // FIXME: If we ever want to show these implicit accesses, this will be
2359 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002360 if (M->isImplicitAccess())
2361 return;
2362
2363 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2364 // real field that that we are interested in.
2365 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2366 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2367 if (FD->isAnonymousStructOrUnion()) {
2368 AddStmt(SubME->getBase());
2369 return;
2370 }
2371 }
2372 }
2373
2374 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002375}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 AddTypeLoc(E->getEncodedTypeSourceInfo());
2378}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 EnqueueChildren(M);
2381 AddTypeLoc(M->getClassReceiverTypeInfo());
2382}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit the components of the offsetof expression.
2385 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2386 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2387 const OffsetOfNode &Node = E->getComponent(I-1);
2388 switch (Node.getKind()) {
2389 case OffsetOfNode::Array:
2390 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2391 break;
2392 case OffsetOfNode::Field:
2393 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2394 break;
2395 case OffsetOfNode::Identifier:
2396 case OffsetOfNode::Base:
2397 continue;
2398 }
2399 }
2400 // Visit the type into which we're computing the offset.
2401 AddTypeLoc(E->getTypeSourceInfo());
2402}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2405 WL.push_back(OverloadExprParts(E, Parent));
2406}
2407void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 EnqueueChildren(E);
2410 if (E->isArgumentType())
2411 AddTypeLoc(E->getArgumentTypeInfo());
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 EnqueueChildren(S);
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 AddStmt(S->getBody());
2418 AddStmt(S->getCond());
2419 AddDecl(S->getConditionVariable());
2420}
2421
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 AddStmt(W->getBody());
2424 AddStmt(W->getCond());
2425 AddDecl(W->getConditionVariable());
2426}
2427
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 for (unsigned I = E->getNumArgs(); I > 0; --I)
2430 AddTypeLoc(E->getArg(I-1));
2431}
2432
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 AddTypeLoc(E->getQueriedTypeSourceInfo());
2435}
2436
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 EnqueueChildren(E);
2439}
2440
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 VisitOverloadExpr(U);
2443 if (!U->isImplicitAccess())
2444 AddStmt(U->getBase());
2445}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 AddStmt(E->getSubExpr());
2448 AddTypeLoc(E->getWrittenTypeInfo());
2449}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 WL.push_back(SizeOfPackExprParts(E, Parent));
2452}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002453void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 // If the opaque value has a source expression, just transparently
2455 // visit that. This is useful for (e.g.) pseudo-object expressions.
2456 if (Expr *SourceExpr = E->getSourceExpr())
2457 return Visit(SourceExpr);
2458}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002459void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 AddStmt(E->getBody());
2461 WL.push_back(LambdaExprParts(E, Parent));
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 // Treat the expression like its syntactic form.
2465 Visit(E->getSyntacticForm());
2466}
2467
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002468void EnqueueVisitor::VisitOMPExecutableDirective(
2469 const OMPExecutableDirective *D) {
2470 EnqueueChildren(D);
2471 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2472 E = D->clauses().end();
2473 I != E; ++I)
2474 EnqueueChildren(*I);
2475}
2476
Alexander Musman3aaab662014-08-19 11:27:13 +00002477void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2478 VisitOMPExecutableDirective(D);
2479}
2480
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002481void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2482 VisitOMPExecutableDirective(D);
2483}
2484
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002485void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002486 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002487}
2488
Alexey Bataevf29276e2014-06-18 04:14:57 +00002489void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002490 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002491}
2492
Alexander Musmanf82886e2014-09-18 05:12:34 +00002493void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2494 VisitOMPLoopDirective(D);
2495}
2496
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002497void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002501void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503}
2504
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002505void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2506 VisitOMPExecutableDirective(D);
2507}
2508
Alexander Musman80c22892014-07-17 08:54:58 +00002509void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2510 VisitOMPExecutableDirective(D);
2511}
2512
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002513void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2514 VisitOMPExecutableDirective(D);
2515 AddDeclarationNameInfo(D);
2516}
2517
Alexey Bataev4acb8592014-07-07 13:01:15 +00002518void
2519EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002520 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002521}
2522
Alexander Musmane4e893b2014-09-23 09:33:00 +00002523void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2524 const OMPParallelForSimdDirective *D) {
2525 VisitOMPLoopDirective(D);
2526}
2527
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002528void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2529 const OMPParallelSectionsDirective *D) {
2530 VisitOMPExecutableDirective(D);
2531}
2532
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002533void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2534 VisitOMPExecutableDirective(D);
2535}
2536
Alexey Bataev68446b72014-07-18 07:47:19 +00002537void
2538EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002542void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev2df347a2014-07-18 10:17:07 +00002546void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002550void EnqueueVisitor::VisitOMPTaskgroupDirective(
2551 const OMPTaskgroupDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev6125da92014-07-21 11:26:11 +00002555void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002559void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev0162e452014-07-22 10:10:35 +00002563void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002567void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Michael Wong65f367f2015-07-21 13:44:28 +00002571void EnqueueVisitor::VisitOMPTargetDataDirective(const
2572 OMPTargetDataDirective *D) {
2573 VisitOMPExecutableDirective(D);
2574}
2575
Alexey Bataev13314bf2014-10-09 04:18:56 +00002576void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002580void EnqueueVisitor::VisitOMPCancellationPointDirective(
2581 const OMPCancellationPointDirective *D) {
2582 VisitOMPExecutableDirective(D);
2583}
2584
Alexey Bataev80909872015-07-02 11:25:17 +00002585void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2586 VisitOMPExecutableDirective(D);
2587}
2588
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002589void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2591}
2592
2593bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2594 if (RegionOfInterest.isValid()) {
2595 SourceRange Range = getRawCursorExtent(C);
2596 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2597 return false;
2598 }
2599 return true;
2600}
2601
2602bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2603 while (!WL.empty()) {
2604 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002605 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002606
2607 // Set the Parent field, then back to its old value once we're done.
2608 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2609
2610 switch (LI.getKind()) {
2611 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002612 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 if (!D)
2614 continue;
2615
2616 // For now, perform default visitation for Decls.
2617 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2618 cast<DeclVisit>(&LI)->isFirst())))
2619 return true;
2620
2621 continue;
2622 }
2623 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2624 const ASTTemplateArgumentListInfo *ArgList =
2625 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2626 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2627 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2628 Arg != ArgEnd; ++Arg) {
2629 if (VisitTemplateArgumentLoc(*Arg))
2630 return true;
2631 }
2632 continue;
2633 }
2634 case VisitorJob::TypeLocVisitKind: {
2635 // Perform default visitation for TypeLocs.
2636 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2637 return true;
2638 continue;
2639 }
2640 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002641 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 if (LabelStmt *stmt = LS->getStmt()) {
2643 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2644 TU))) {
2645 return true;
2646 }
2647 }
2648 continue;
2649 }
2650
2651 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2652 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2653 if (VisitNestedNameSpecifierLoc(V->get()))
2654 return true;
2655 continue;
2656 }
2657
2658 case VisitorJob::DeclarationNameInfoVisitKind: {
2659 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2660 ->get()))
2661 return true;
2662 continue;
2663 }
2664 case VisitorJob::MemberRefVisitKind: {
2665 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2666 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2667 return true;
2668 continue;
2669 }
2670 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002671 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002672 if (!S)
2673 continue;
2674
2675 // Update the current cursor.
2676 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2677 if (!IsInRegionOfInterest(Cursor))
2678 continue;
2679 switch (Visitor(Cursor, Parent, ClientData)) {
2680 case CXChildVisit_Break: return true;
2681 case CXChildVisit_Continue: break;
2682 case CXChildVisit_Recurse:
2683 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002684 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002685 EnqueueWorkList(WL, S);
2686 break;
2687 }
2688 continue;
2689 }
2690 case VisitorJob::MemberExprPartsKind: {
2691 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002692 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002693
2694 // Visit the nested-name-specifier
2695 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2696 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2697 return true;
2698
2699 // Visit the declaration name.
2700 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2701 return true;
2702
2703 // Visit the explicitly-specified template arguments, if any.
2704 if (M->hasExplicitTemplateArgs()) {
2705 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2706 *ArgEnd = Arg + M->getNumTemplateArgs();
2707 Arg != ArgEnd; ++Arg) {
2708 if (VisitTemplateArgumentLoc(*Arg))
2709 return true;
2710 }
2711 }
2712 continue;
2713 }
2714 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002715 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 // Visit nested-name-specifier, if present.
2717 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2718 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2719 return true;
2720 // Visit declaration name.
2721 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2722 return true;
2723 continue;
2724 }
2725 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002726 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002727 // Visit the nested-name-specifier.
2728 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2729 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2730 return true;
2731 // Visit the declaration name.
2732 if (VisitDeclarationNameInfo(O->getNameInfo()))
2733 return true;
2734 // Visit the overloaded declaration reference.
2735 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2736 return true;
2737 continue;
2738 }
2739 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002740 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 NamedDecl *Pack = E->getPack();
2742 if (isa<TemplateTypeParmDecl>(Pack)) {
2743 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2744 E->getPackLoc(), TU)))
2745 return true;
2746
2747 continue;
2748 }
2749
2750 if (isa<TemplateTemplateParmDecl>(Pack)) {
2751 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2752 E->getPackLoc(), TU)))
2753 return true;
2754
2755 continue;
2756 }
2757
2758 // Non-type template parameter packs and function parameter packs are
2759 // treated like DeclRefExpr cursors.
2760 continue;
2761 }
2762
2763 case VisitorJob::LambdaExprPartsKind: {
2764 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002765 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2767 CEnd = E->explicit_capture_end();
2768 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002769 // FIXME: Lambda init-captures.
2770 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002772
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2774 C->getLocation(),
2775 TU)))
2776 return true;
2777 }
2778
2779 // Visit parameters and return type, if present.
2780 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2781 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2782 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2783 // Visit the whole type.
2784 if (Visit(TL))
2785 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002786 } else if (FunctionProtoTypeLoc Proto =
2787 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 if (E->hasExplicitParameters()) {
2789 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002790 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2791 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 return true;
2793 } else {
2794 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002795 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 return true;
2797 }
2798 }
2799 }
2800 break;
2801 }
2802
2803 case VisitorJob::PostChildrenVisitKind:
2804 if (PostChildrenVisitor(Parent, ClientData))
2805 return true;
2806 break;
2807 }
2808 }
2809 return false;
2810}
2811
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002812bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002813 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 if (!WorkListFreeList.empty()) {
2815 WL = WorkListFreeList.back();
2816 WL->clear();
2817 WorkListFreeList.pop_back();
2818 }
2819 else {
2820 WL = new VisitorWorkList();
2821 WorkListCache.push_back(WL);
2822 }
2823 EnqueueWorkList(*WL, S);
2824 bool result = RunVisitorWorkList(*WL);
2825 WorkListFreeList.push_back(WL);
2826 return result;
2827}
2828
2829namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002830typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002831RefNamePieces
2832buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2833 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2834 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2836 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2837 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2838
2839 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2840
2841 RefNamePieces Pieces;
2842
2843 if (WantQualifier && QLoc.isValid())
2844 Pieces.push_back(QLoc);
2845
2846 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2847 Pieces.push_back(NI.getLoc());
2848
2849 if (WantTemplateArgs && TemplateArgs)
2850 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2851 TemplateArgs->RAngleLoc));
2852
2853 if (Kind == DeclarationName::CXXOperatorName) {
2854 Pieces.push_back(SourceLocation::getFromRawEncoding(
2855 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2856 Pieces.push_back(SourceLocation::getFromRawEncoding(
2857 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2858 }
2859
2860 if (WantSinglePiece) {
2861 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2862 Pieces.clear();
2863 Pieces.push_back(R);
2864 }
2865
2866 return Pieces;
2867}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002868}
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
2870//===----------------------------------------------------------------------===//
2871// Misc. API hooks.
2872//===----------------------------------------------------------------------===//
2873
Chad Rosier05c71aa2013-03-27 18:28:23 +00002874static void fatal_error_handler(void *user_data, const std::string& reason,
2875 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 // Write the result out to stderr avoiding errs() because raw_ostreams can
2877 // call report_fatal_error.
2878 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2879 ::abort();
2880}
2881
Chandler Carruth66660742014-06-27 16:37:27 +00002882namespace {
2883struct RegisterFatalErrorHandler {
2884 RegisterFatalErrorHandler() {
2885 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2886 }
2887};
2888}
2889
2890static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2891
Guy Benyei11169dd2012-12-18 14:30:41 +00002892extern "C" {
2893CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2894 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 // We use crash recovery to make some of our APIs more reliable, implicitly
2896 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002897 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2898 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002899
Chandler Carruth66660742014-06-27 16:37:27 +00002900 // Look through the managed static to trigger construction of the managed
2901 // static which registers our fatal error handler. This ensures it is only
2902 // registered once.
2903 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002904
Adrian Prantlbc068582015-07-08 01:00:30 +00002905 // Initialize targets for clang module support.
2906 llvm::InitializeAllTargets();
2907 llvm::InitializeAllTargetMCs();
2908 llvm::InitializeAllAsmPrinters();
2909 llvm::InitializeAllAsmParsers();
2910
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002911 CIndexer *CIdxr = new CIndexer();
2912
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 if (excludeDeclarationsFromPCH)
2914 CIdxr->setOnlyLocalDecls();
2915 if (displayDiagnostics)
2916 CIdxr->setDisplayDiagnostics();
2917
2918 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2919 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2920 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2921 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2922 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2923 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2924
2925 return CIdxr;
2926}
2927
2928void clang_disposeIndex(CXIndex CIdx) {
2929 if (CIdx)
2930 delete static_cast<CIndexer *>(CIdx);
2931}
2932
2933void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2934 if (CIdx)
2935 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2936}
2937
2938unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2939 if (CIdx)
2940 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2941 return 0;
2942}
2943
2944void clang_toggleCrashRecovery(unsigned isEnabled) {
2945 if (isEnabled)
2946 llvm::CrashRecoveryContext::Enable();
2947 else
2948 llvm::CrashRecoveryContext::Disable();
2949}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002950
Guy Benyei11169dd2012-12-18 14:30:41 +00002951CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2952 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002953 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002954 enum CXErrorCode Result =
2955 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002956 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 assert((TU && Result == CXError_Success) ||
2958 (!TU && Result != CXError_Success));
2959 return TU;
2960}
2961
2962enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2963 const char *ast_filename,
2964 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002965 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002966 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002967
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002968 if (!CIdx || !ast_filename || !out_TU)
2969 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002970
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002971 LOG_FUNC_SECTION {
2972 *Log << ast_filename;
2973 }
2974
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2976 FileSystemOptions FileSystemOpts;
2977
Justin Bognerd512c1e2014-10-15 00:33:06 +00002978 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2979 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002980 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002981 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002982 FileSystemOpts, /*UseDebugInfo=*/false,
2983 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002984 /*CaptureDiagnostics=*/true,
2985 /*AllowPCHWithCompilerErrors=*/true,
2986 /*UserFilesAreVolatile=*/true);
2987 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002989}
2990
2991unsigned clang_defaultEditingTranslationUnitOptions() {
2992 return CXTranslationUnit_PrecompiledPreamble |
2993 CXTranslationUnit_CacheCompletionResults;
2994}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995
Guy Benyei11169dd2012-12-18 14:30:41 +00002996CXTranslationUnit
2997clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2998 const char *source_filename,
2999 int num_command_line_args,
3000 const char * const *command_line_args,
3001 unsigned num_unsaved_files,
3002 struct CXUnsavedFile *unsaved_files) {
3003 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3004 return clang_parseTranslationUnit(CIdx, source_filename,
3005 command_line_args, num_command_line_args,
3006 unsaved_files, num_unsaved_files,
3007 Options);
3008}
3009
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003010static CXErrorCode
3011clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3012 const char *const *command_line_args,
3013 int num_command_line_args,
3014 ArrayRef<CXUnsavedFile> unsaved_files,
3015 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003016 // Set up the initial return values.
3017 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003018 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003019
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003021 if (!CIdx || !out_TU)
3022 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023
Guy Benyei11169dd2012-12-18 14:30:41 +00003024 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3025
3026 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3027 setThreadBackgroundPriority();
3028
3029 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3030 // FIXME: Add a flag for modules.
3031 TranslationUnitKind TUKind
3032 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003033 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 = options & CXTranslationUnit_CacheCompletionResults;
3035 bool IncludeBriefCommentsInCodeCompletion
3036 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3037 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3038 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3039
3040 // Configure the diagnostics.
3041 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003042 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003043
3044 // Recover resources if we crash before exiting this function.
3045 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3046 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003047 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
Ahmed Charlesb8984322014-03-07 20:03:18 +00003049 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3050 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003051
3052 // Recover resources if we crash before exiting this function.
3053 llvm::CrashRecoveryContextCleanupRegistrar<
3054 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3055
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003056 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003057 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003058 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003059 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 }
3061
Ahmed Charlesb8984322014-03-07 20:03:18 +00003062 std::unique_ptr<std::vector<const char *>> Args(
3063 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
3065 // Recover resources if we crash before exiting this method.
3066 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3067 ArgsCleanup(Args.get());
3068
3069 // Since the Clang C library is primarily used by batch tools dealing with
3070 // (often very broken) source code, where spell-checking can have a
3071 // significant negative impact on performance (particularly when
3072 // precompiled headers are involved), we disable it by default.
3073 // Only do this if we haven't found a spell-checking-related argument.
3074 bool FoundSpellCheckingArgument = false;
3075 for (int I = 0; I != num_command_line_args; ++I) {
3076 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3077 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3078 FoundSpellCheckingArgument = true;
3079 break;
3080 }
3081 }
3082 if (!FoundSpellCheckingArgument)
3083 Args->push_back("-fno-spell-checking");
3084
3085 Args->insert(Args->end(), command_line_args,
3086 command_line_args + num_command_line_args);
3087
3088 // The 'source_filename' argument is optional. If the caller does not
3089 // specify it then it is assumed that the source file is specified
3090 // in the actual argument list.
3091 // Put the source file after command_line_args otherwise if '-x' flag is
3092 // present it will be unused.
3093 if (source_filename)
3094 Args->push_back(source_filename);
3095
3096 // Do we need the detailed preprocessing record?
3097 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3098 Args->push_back("-Xclang");
3099 Args->push_back("-detailed-preprocessing-record");
3100 }
3101
3102 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003103 std::unique_ptr<ASTUnit> ErrUnit;
3104 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003105 Args->data(), Args->data() + Args->size(),
3106 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003107 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3108 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3109 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3110 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3111 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3112 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003114 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003115 if (!Unit && !ErrUnit)
3116 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003117
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 if (NumErrors != Diags->getClient()->getNumErrors()) {
3119 // Make sure to check that 'Unit' is non-NULL.
3120 if (CXXIdx->getDisplayDiagnostics())
3121 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3122 }
3123
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003124 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3125 return CXError_ASTReadError;
3126
3127 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3128 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003129}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003130
3131CXTranslationUnit
3132clang_parseTranslationUnit(CXIndex CIdx,
3133 const char *source_filename,
3134 const char *const *command_line_args,
3135 int num_command_line_args,
3136 struct CXUnsavedFile *unsaved_files,
3137 unsigned num_unsaved_files,
3138 unsigned options) {
3139 CXTranslationUnit TU;
3140 enum CXErrorCode Result = clang_parseTranslationUnit2(
3141 CIdx, source_filename, command_line_args, num_command_line_args,
3142 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003143 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003144 assert((TU && Result == CXError_Success) ||
3145 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003146 return TU;
3147}
3148
3149enum CXErrorCode clang_parseTranslationUnit2(
3150 CXIndex CIdx,
3151 const char *source_filename,
3152 const char *const *command_line_args,
3153 int num_command_line_args,
3154 struct CXUnsavedFile *unsaved_files,
3155 unsigned num_unsaved_files,
3156 unsigned options,
3157 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003158 LOG_FUNC_SECTION {
3159 *Log << source_filename << ": ";
3160 for (int i = 0; i != num_command_line_args; ++i)
3161 *Log << command_line_args[i] << " ";
3162 }
3163
Alp Toker9d85b182014-07-07 01:23:14 +00003164 if (num_unsaved_files && !unsaved_files)
3165 return CXError_InvalidArguments;
3166
Alp Toker5c532982014-07-07 22:42:03 +00003167 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003168 auto ParseTranslationUnitImpl = [=, &result] {
3169 result = clang_parseTranslationUnit_Impl(
3170 CIdx, source_filename, command_line_args, num_command_line_args,
3171 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3172 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 llvm::CrashRecoveryContext CRC;
3174
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003175 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3177 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3178 fprintf(stderr, " 'command_line_args' : [");
3179 for (int i = 0; i != num_command_line_args; ++i) {
3180 if (i)
3181 fprintf(stderr, ", ");
3182 fprintf(stderr, "'%s'", command_line_args[i]);
3183 }
3184 fprintf(stderr, "],\n");
3185 fprintf(stderr, " 'unsaved_files' : [");
3186 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3187 if (i)
3188 fprintf(stderr, ", ");
3189 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3190 unsaved_files[i].Length);
3191 }
3192 fprintf(stderr, "],\n");
3193 fprintf(stderr, " 'options' : %d,\n", options);
3194 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003195
3196 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003198 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003199 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 }
Alp Toker5c532982014-07-07 22:42:03 +00003201
3202 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003203}
3204
3205unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3206 return CXSaveTranslationUnit_None;
3207}
3208
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003209static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3210 const char *FileName,
3211 unsigned options) {
3212 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3214 setThreadBackgroundPriority();
3215
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003216 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3217 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003218}
3219
3220int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3221 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003222 LOG_FUNC_SECTION {
3223 *Log << TU << ' ' << FileName;
3224 }
3225
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003226 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003227 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003229 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003230
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003231 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3233 if (!CXXUnit->hasSema())
3234 return CXSaveError_InvalidTU;
3235
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003236 CXSaveError result;
3237 auto SaveTranslationUnitImpl = [=, &result]() {
3238 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3239 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003240
3241 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3242 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003243 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003244
3245 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3246 PrintLibclangResourceUsage(TU);
3247
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003248 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 }
3250
3251 // We have an AST that has invalid nodes due to compiler errors.
3252 // Use a crash recovery thread for protection.
3253
3254 llvm::CrashRecoveryContext CRC;
3255
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003256 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3258 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3259 fprintf(stderr, " 'options' : %d,\n", options);
3260 fprintf(stderr, "}\n");
3261
3262 return CXSaveError_Unknown;
3263
3264 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3265 PrintLibclangResourceUsage(TU);
3266 }
3267
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003268 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269}
3270
3271void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3272 if (CTUnit) {
3273 // If the translation unit has been marked as unsafe to free, just discard
3274 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003275 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3276 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 return;
3278
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003279 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003280 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3282 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003283 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 delete CTUnit;
3285 }
3286}
3287
3288unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3289 return CXReparse_None;
3290}
3291
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003292static CXErrorCode
3293clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3294 ArrayRef<CXUnsavedFile> unsaved_files,
3295 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003296 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003297 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003298 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003299 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003300 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003301
3302 // Reset the associated diagnostics.
3303 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003304 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003306 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3308 setThreadBackgroundPriority();
3309
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003310 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003312
3313 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3314 new std::vector<ASTUnit::RemappedFile>());
3315
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 // Recover resources if we crash before exiting this function.
3317 llvm::CrashRecoveryContextCleanupRegistrar<
3318 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003319
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003320 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003321 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003322 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003323 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003325
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003326 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3327 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003328 return CXError_Success;
3329 if (isASTReadError(CXXUnit))
3330 return CXError_ASTReadError;
3331 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332}
3333
3334int clang_reparseTranslationUnit(CXTranslationUnit TU,
3335 unsigned num_unsaved_files,
3336 struct CXUnsavedFile *unsaved_files,
3337 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003338 LOG_FUNC_SECTION {
3339 *Log << TU;
3340 }
3341
Alp Toker9d85b182014-07-07 01:23:14 +00003342 if (num_unsaved_files && !unsaved_files)
3343 return CXError_InvalidArguments;
3344
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003345 CXErrorCode result;
3346 auto ReparseTranslationUnitImpl = [=, &result]() {
3347 result = clang_reparseTranslationUnit_Impl(
3348 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3349 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003350
3351 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003352 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003353 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355
3356 llvm::CrashRecoveryContext CRC;
3357
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003358 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003360 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003361 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3363 PrintLibclangResourceUsage(TU);
3364
Alp Toker5c532982014-07-07 22:42:03 +00003365 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366}
3367
3368
3369CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003370 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003371 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003372 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003373 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003374
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003375 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377}
3378
3379CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003380 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003381 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003382 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003383 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003384
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003385 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3387}
3388
3389} // end: extern "C"
3390
3391//===----------------------------------------------------------------------===//
3392// CXFile Operations.
3393//===----------------------------------------------------------------------===//
3394
3395extern "C" {
3396CXString clang_getFileName(CXFile SFile) {
3397 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003398 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003399
3400 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003401 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003402}
3403
3404time_t clang_getFileTime(CXFile SFile) {
3405 if (!SFile)
3406 return 0;
3407
3408 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3409 return FEnt->getModificationTime();
3410}
3411
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003412CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003413 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003414 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003415 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003416 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003418 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
3420 FileManager &FMgr = CXXUnit->getFileManager();
3421 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3422}
3423
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003424unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3425 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003426 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003427 LOG_BAD_TU(TU);
3428 return 0;
3429 }
3430
3431 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 return 0;
3433
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003434 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 FileEntry *FEnt = static_cast<FileEntry *>(file);
3436 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3437 .isFileMultipleIncludeGuarded(FEnt);
3438}
3439
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003440int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3441 if (!file || !outID)
3442 return 1;
3443
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003444 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003445 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3446 outID->data[0] = ID.getDevice();
3447 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003448 outID->data[2] = FEnt->getModificationTime();
3449 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003450}
3451
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003452int clang_File_isEqual(CXFile file1, CXFile file2) {
3453 if (file1 == file2)
3454 return true;
3455
3456 if (!file1 || !file2)
3457 return false;
3458
3459 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3460 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3461 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3462}
3463
Guy Benyei11169dd2012-12-18 14:30:41 +00003464} // end: extern "C"
3465
3466//===----------------------------------------------------------------------===//
3467// CXCursor Operations.
3468//===----------------------------------------------------------------------===//
3469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470static const Decl *getDeclFromExpr(const Stmt *E) {
3471 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 return getDeclFromExpr(CE->getSubExpr());
3473
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003474 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 if (PRE->isExplicitProperty())
3482 return PRE->getExplicitProperty();
3483 // It could be messaging both getter and setter as in:
3484 // ++myobj.myprop;
3485 // in which case prefer to associate the setter since it is less obvious
3486 // from inspecting the source that the setter is going to get called.
3487 if (PRE->isMessagingSetter())
3488 return PRE->getImplicitPropertySetter();
3489 return PRE->getImplicitPropertyGetter();
3490 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003493 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 if (Expr *Src = OVE->getSourceExpr())
3495 return getDeclFromExpr(Src);
3496
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 if (!CE->isElidable())
3501 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 return OME->getMethodDecl();
3504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3509 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3512 isa<ParmVarDecl>(SizeOfPack->getPack()))
3513 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003514
3515 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003516}
3517
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003518static SourceLocation getLocationFromExpr(const Expr *E) {
3519 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return getLocationFromExpr(CE->getSubExpr());
3521
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003522 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003524 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003526 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003528 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003530 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 return PropRef->getLocation();
3534
3535 return E->getLocStart();
3536}
3537
3538extern "C" {
3539
3540unsigned clang_visitChildren(CXCursor parent,
3541 CXCursorVisitor visitor,
3542 CXClientData client_data) {
3543 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3544 /*VisitPreprocessorLast=*/false);
3545 return CursorVis.VisitChildren(parent);
3546}
3547
3548#ifndef __has_feature
3549#define __has_feature(x) 0
3550#endif
3551#if __has_feature(blocks)
3552typedef enum CXChildVisitResult
3553 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3554
3555static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3556 CXClientData client_data) {
3557 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3558 return block(cursor, parent);
3559}
3560#else
3561// If we are compiled with a compiler that doesn't have native blocks support,
3562// define and call the block manually, so the
3563typedef struct _CXChildVisitResult
3564{
3565 void *isa;
3566 int flags;
3567 int reserved;
3568 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3569 CXCursor);
3570} *CXCursorVisitorBlock;
3571
3572static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3573 CXClientData client_data) {
3574 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3575 return block->invoke(block, cursor, parent);
3576}
3577#endif
3578
3579
3580unsigned clang_visitChildrenWithBlock(CXCursor parent,
3581 CXCursorVisitorBlock block) {
3582 return clang_visitChildren(parent, visitWithBlock, block);
3583}
3584
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003585static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003587 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003588
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003589 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003591 if (const ObjCPropertyImplDecl *PropImpl =
3592 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003596 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003600 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 }
3602
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003603 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003606 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3608 // and returns different names. NamedDecl returns the class name and
3609 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
3612 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003613 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003614
3615 SmallString<1024> S;
3616 llvm::raw_svector_ostream os(S);
3617 ND->printName(os);
3618
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003620}
3621
3622CXString clang_getCursorSpelling(CXCursor C) {
3623 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003624 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003625
3626 if (clang_isReference(C.kind)) {
3627 switch (C.kind) {
3628 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003629 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
3632 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 }
3636 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003637 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 }
3641 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003642 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003643 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 }
3645 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003646 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 assert(Type && "Missing type decl");
3648
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003649 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 getAsString());
3651 }
3652 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003653 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 assert(Template && "Missing template decl");
3655
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003656 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 }
3658
3659 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003660 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 assert(NS && "Missing namespace decl");
3662
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003663 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 }
3665
3666 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003667 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 assert(Field && "Missing member decl");
3669
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003670 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 }
3672
3673 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003674 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 assert(Label && "Missing label");
3676
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 }
3679
3680 case CXCursor_OverloadedDeclRef: {
3681 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003682 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3683 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003684 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003685 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003687 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003688 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 OverloadedTemplateStorage *Ovl
3690 = Storage.get<OverloadedTemplateStorage*>();
3691 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003692 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003693 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 }
3695
3696 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003697 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 assert(Var && "Missing variable decl");
3699
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003700 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 }
3702
3703 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 }
3706 }
3707
3708 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003709 const Expr *E = getCursorExpr(C);
3710
3711 if (C.kind == CXCursor_ObjCStringLiteral ||
3712 C.kind == CXCursor_StringLiteral) {
3713 const StringLiteral *SLit;
3714 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3715 SLit = OSL->getString();
3716 } else {
3717 SLit = cast<StringLiteral>(E);
3718 }
3719 SmallString<256> Buf;
3720 llvm::raw_svector_ostream OS(Buf);
3721 SLit->outputString(OS);
3722 return cxstring::createDup(OS.str());
3723 }
3724
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003725 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 if (D)
3727 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003728 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 }
3730
3731 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003732 const Stmt *S = getCursorStmt(C);
3733 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003735
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003736 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 }
3738
3739 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 ->getNameStart());
3742
3743 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 ->getNameStart());
3746
3747 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003748 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003749
3750 if (clang_isDeclaration(C.kind))
3751 return getDeclSpelling(getCursorDecl(C));
3752
3753 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003754 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003755 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 }
3757
3758 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003759 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003760 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 }
3762
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003763 if (C.kind == CXCursor_PackedAttr) {
3764 return cxstring::createRef("packed");
3765 }
3766
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003767 if (C.kind == CXCursor_VisibilityAttr) {
3768 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3769 switch (AA->getVisibility()) {
3770 case VisibilityAttr::VisibilityType::Default:
3771 return cxstring::createRef("default");
3772 case VisibilityAttr::VisibilityType::Hidden:
3773 return cxstring::createRef("hidden");
3774 case VisibilityAttr::VisibilityType::Protected:
3775 return cxstring::createRef("protected");
3776 }
3777 llvm_unreachable("unknown visibility type");
3778 }
3779
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003780 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003781}
3782
3783CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3784 unsigned pieceIndex,
3785 unsigned options) {
3786 if (clang_Cursor_isNull(C))
3787 return clang_getNullRange();
3788
3789 ASTContext &Ctx = getCursorContext(C);
3790
3791 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003792 const Stmt *S = getCursorStmt(C);
3793 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 if (pieceIndex > 0)
3795 return clang_getNullRange();
3796 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3797 }
3798
3799 return clang_getNullRange();
3800 }
3801
3802 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003803 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3805 if (pieceIndex >= ME->getNumSelectorLocs())
3806 return clang_getNullRange();
3807 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3808 }
3809 }
3810
3811 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3812 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003813 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3815 if (pieceIndex >= MD->getNumSelectorLocs())
3816 return clang_getNullRange();
3817 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3818 }
3819 }
3820
3821 if (C.kind == CXCursor_ObjCCategoryDecl ||
3822 C.kind == CXCursor_ObjCCategoryImplDecl) {
3823 if (pieceIndex > 0)
3824 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003825 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3827 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003828 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3830 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3831 }
3832
3833 if (C.kind == CXCursor_ModuleImportDecl) {
3834 if (pieceIndex > 0)
3835 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003836 if (const ImportDecl *ImportD =
3837 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3839 if (!Locs.empty())
3840 return cxloc::translateSourceRange(Ctx,
3841 SourceRange(Locs.front(), Locs.back()));
3842 }
3843 return clang_getNullRange();
3844 }
3845
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003846 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3847 C.kind == CXCursor_ConversionFunction) {
3848 if (pieceIndex > 0)
3849 return clang_getNullRange();
3850 if (const FunctionDecl *FD =
3851 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3852 DeclarationNameInfo FunctionName = FD->getNameInfo();
3853 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3854 }
3855 return clang_getNullRange();
3856 }
3857
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 // FIXME: A CXCursor_InclusionDirective should give the location of the
3859 // filename, but we don't keep track of this.
3860
3861 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3862 // but we don't keep track of this.
3863
3864 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3865 // but we don't keep track of this.
3866
3867 // Default handling, give the location of the cursor.
3868
3869 if (pieceIndex > 0)
3870 return clang_getNullRange();
3871
3872 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3873 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3874 return cxloc::translateSourceRange(Ctx, Loc);
3875}
3876
Eli Bendersky44a206f2014-07-31 18:04:56 +00003877CXString clang_Cursor_getMangling(CXCursor C) {
3878 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3879 return cxstring::createEmpty();
3880
Eli Bendersky44a206f2014-07-31 18:04:56 +00003881 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003882 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003883 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3884 return cxstring::createEmpty();
3885
Eli Bendersky79759592014-08-01 15:01:10 +00003886 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003887 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003888 ASTContext &Ctx = ND->getASTContext();
3889 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003890
Eli Bendersky79759592014-08-01 15:01:10 +00003891 std::string FrontendBuf;
3892 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3893 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003894
Eli Bendersky79759592014-08-01 15:01:10 +00003895 // Now apply backend mangling.
3896 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003897 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003898
3899 std::string FinalBuf;
3900 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003901 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3902 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003903
3904 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003905}
3906
Guy Benyei11169dd2012-12-18 14:30:41 +00003907CXString clang_getCursorDisplayName(CXCursor C) {
3908 if (!clang_isDeclaration(C.kind))
3909 return clang_getCursorSpelling(C);
3910
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003911 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003913 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003914
3915 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 D = FunTmpl->getTemplatedDecl();
3918
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 SmallString<64> Str;
3921 llvm::raw_svector_ostream OS(Str);
3922 OS << *Function;
3923 if (Function->getPrimaryTemplate())
3924 OS << "<>";
3925 OS << "(";
3926 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3927 if (I)
3928 OS << ", ";
3929 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3930 }
3931
3932 if (Function->isVariadic()) {
3933 if (Function->getNumParams())
3934 OS << ", ";
3935 OS << "...";
3936 }
3937 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003938 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 }
3940
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 SmallString<64> Str;
3943 llvm::raw_svector_ostream OS(Str);
3944 OS << *ClassTemplate;
3945 OS << "<";
3946 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3947 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3948 if (I)
3949 OS << ", ";
3950
3951 NamedDecl *Param = Params->getParam(I);
3952 if (Param->getIdentifier()) {
3953 OS << Param->getIdentifier()->getName();
3954 continue;
3955 }
3956
3957 // There is no parameter name, which makes this tricky. Try to come up
3958 // with something useful that isn't too long.
3959 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3960 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3961 else if (NonTypeTemplateParmDecl *NTTP
3962 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3963 OS << NTTP->getType().getAsString(Policy);
3964 else
3965 OS << "template<...> class";
3966 }
3967
3968 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003969 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 }
3971
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003972 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3974 // If the type was explicitly written, use that.
3975 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003976 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003977
Benjamin Kramer9170e912013-02-22 15:46:01 +00003978 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 llvm::raw_svector_ostream OS(Str);
3980 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003981 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 ClassSpec->getTemplateArgs().data(),
3983 ClassSpec->getTemplateArgs().size(),
3984 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003985 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 }
3987
3988 return clang_getCursorSpelling(C);
3989}
3990
3991CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3992 switch (Kind) {
3993 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004071 case CXCursor_OMPArraySectionExpr:
4072 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004123 case CXCursor_ObjCSelfExpr:
4124 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004213 case CXCursor_SEHLeaveStmt:
4214 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004243 case CXCursor_PackedAttr:
4244 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004245 case CXCursor_PureAttr:
4246 return cxstring::createRef("attribute(pure)");
4247 case CXCursor_ConstAttr:
4248 return cxstring::createRef("attribute(const)");
4249 case CXCursor_NoDuplicateAttr:
4250 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004251 case CXCursor_CUDAConstantAttr:
4252 return cxstring::createRef("attribute(constant)");
4253 case CXCursor_CUDADeviceAttr:
4254 return cxstring::createRef("attribute(device)");
4255 case CXCursor_CUDAGlobalAttr:
4256 return cxstring::createRef("attribute(global)");
4257 case CXCursor_CUDAHostAttr:
4258 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004259 case CXCursor_CUDASharedAttr:
4260 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004261 case CXCursor_VisibilityAttr:
4262 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004311 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004312 return cxstring::createRef("OMPParallelDirective");
4313 case CXCursor_OMPSimdDirective:
4314 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004315 case CXCursor_OMPForDirective:
4316 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004317 case CXCursor_OMPForSimdDirective:
4318 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004319 case CXCursor_OMPSectionsDirective:
4320 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004321 case CXCursor_OMPSectionDirective:
4322 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004323 case CXCursor_OMPSingleDirective:
4324 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004325 case CXCursor_OMPMasterDirective:
4326 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004327 case CXCursor_OMPCriticalDirective:
4328 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004329 case CXCursor_OMPParallelForDirective:
4330 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004331 case CXCursor_OMPParallelForSimdDirective:
4332 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004333 case CXCursor_OMPParallelSectionsDirective:
4334 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004335 case CXCursor_OMPTaskDirective:
4336 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004337 case CXCursor_OMPTaskyieldDirective:
4338 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004339 case CXCursor_OMPBarrierDirective:
4340 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004341 case CXCursor_OMPTaskwaitDirective:
4342 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004343 case CXCursor_OMPTaskgroupDirective:
4344 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004345 case CXCursor_OMPFlushDirective:
4346 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004347 case CXCursor_OMPOrderedDirective:
4348 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004349 case CXCursor_OMPAtomicDirective:
4350 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004351 case CXCursor_OMPTargetDirective:
4352 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004353 case CXCursor_OMPTargetDataDirective:
4354 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004355 case CXCursor_OMPTeamsDirective:
4356 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004357 case CXCursor_OMPCancellationPointDirective:
4358 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004359 case CXCursor_OMPCancelDirective:
4360 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004361 case CXCursor_OverloadCandidate:
4362 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 }
4364
4365 llvm_unreachable("Unhandled CXCursorKind");
4366}
4367
4368struct GetCursorData {
4369 SourceLocation TokenBeginLoc;
4370 bool PointsAtMacroArgExpansion;
4371 bool VisitedObjCPropertyImplDecl;
4372 SourceLocation VisitedDeclaratorDeclStartLoc;
4373 CXCursor &BestCursor;
4374
4375 GetCursorData(SourceManager &SM,
4376 SourceLocation tokenBegin, CXCursor &outputCursor)
4377 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4378 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4379 VisitedObjCPropertyImplDecl = false;
4380 }
4381};
4382
4383static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4384 CXCursor parent,
4385 CXClientData client_data) {
4386 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4387 CXCursor *BestCursor = &Data->BestCursor;
4388
4389 // If we point inside a macro argument we should provide info of what the
4390 // token is so use the actual cursor, don't replace it with a macro expansion
4391 // cursor.
4392 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4393 return CXChildVisit_Recurse;
4394
4395 if (clang_isDeclaration(cursor.kind)) {
4396 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4399 if (MD->isImplicit())
4400 return CXChildVisit_Break;
4401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4404 // Check that when we have multiple @class references in the same line,
4405 // that later ones do not override the previous ones.
4406 // If we have:
4407 // @class Foo, Bar;
4408 // source ranges for both start at '@', so 'Bar' will end up overriding
4409 // 'Foo' even though the cursor location was at 'Foo'.
4410 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4411 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4414 if (PrevID != ID &&
4415 !PrevID->isThisDeclarationADefinition() &&
4416 !ID->isThisDeclarationADefinition())
4417 return CXChildVisit_Break;
4418 }
4419
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4422 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4423 // Check that when we have multiple declarators in the same line,
4424 // that later ones do not override the previous ones.
4425 // If we have:
4426 // int Foo, Bar;
4427 // source ranges for both start at 'int', so 'Bar' will end up overriding
4428 // 'Foo' even though the cursor location was at 'Foo'.
4429 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4430 return CXChildVisit_Break;
4431 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4435 (void)PropImp;
4436 // Check that when we have multiple @synthesize in the same line,
4437 // that later ones do not override the previous ones.
4438 // If we have:
4439 // @synthesize Foo, Bar;
4440 // source ranges for both start at '@', so 'Bar' will end up overriding
4441 // 'Foo' even though the cursor location was at 'Foo'.
4442 if (Data->VisitedObjCPropertyImplDecl)
4443 return CXChildVisit_Break;
4444 Data->VisitedObjCPropertyImplDecl = true;
4445 }
4446 }
4447
4448 if (clang_isExpression(cursor.kind) &&
4449 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004450 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 // Avoid having the cursor of an expression replace the declaration cursor
4452 // when the expression source range overlaps the declaration range.
4453 // This can happen for C++ constructor expressions whose range generally
4454 // include the variable declaration, e.g.:
4455 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4456 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4457 D->getLocation() == Data->TokenBeginLoc)
4458 return CXChildVisit_Break;
4459 }
4460 }
4461
4462 // If our current best cursor is the construction of a temporary object,
4463 // don't replace that cursor with a type reference, because we want
4464 // clang_getCursor() to point at the constructor.
4465 if (clang_isExpression(BestCursor->kind) &&
4466 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4467 cursor.kind == CXCursor_TypeRef) {
4468 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4469 // as having the actual point on the type reference.
4470 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4471 return CXChildVisit_Recurse;
4472 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004473
4474 // If we already have an Objective-C superclass reference, don't
4475 // update it further.
4476 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4477 return CXChildVisit_Break;
4478
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 *BestCursor = cursor;
4480 return CXChildVisit_Recurse;
4481}
4482
4483CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004484 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004485 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004487 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004488
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004489 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4491
4492 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4493 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4494
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004495 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 CXFile SearchFile;
4497 unsigned SearchLine, SearchColumn;
4498 CXFile ResultFile;
4499 unsigned ResultLine, ResultColumn;
4500 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4501 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4502 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004503
4504 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4505 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004506 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004507 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 SearchFileName = clang_getFileName(SearchFile);
4509 ResultFileName = clang_getFileName(ResultFile);
4510 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4511 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004512 *Log << llvm::format("(%s:%d:%d) = %s",
4513 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4514 clang_getCString(KindSpelling))
4515 << llvm::format("(%s:%d:%d):%s%s",
4516 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4517 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 clang_disposeString(SearchFileName);
4519 clang_disposeString(ResultFileName);
4520 clang_disposeString(KindSpelling);
4521 clang_disposeString(USR);
4522
4523 CXCursor Definition = clang_getCursorDefinition(Result);
4524 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4525 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4526 CXString DefinitionKindSpelling
4527 = clang_getCursorKindSpelling(Definition.kind);
4528 CXFile DefinitionFile;
4529 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004530 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004531 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004533 *Log << llvm::format(" -> %s(%s:%d:%d)",
4534 clang_getCString(DefinitionKindSpelling),
4535 clang_getCString(DefinitionFileName),
4536 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 clang_disposeString(DefinitionFileName);
4538 clang_disposeString(DefinitionKindSpelling);
4539 }
4540 }
4541
4542 return Result;
4543}
4544
4545CXCursor clang_getNullCursor(void) {
4546 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4547}
4548
4549unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004550 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4551 // can't set consistently. For example, when visiting a DeclStmt we will set
4552 // it but we don't set it on the result of clang_getCursorDefinition for
4553 // a reference of the same declaration.
4554 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4555 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4556 // to provide that kind of info.
4557 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004558 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004559 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004560 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004561
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 return X == Y;
4563}
4564
4565unsigned clang_hashCursor(CXCursor C) {
4566 unsigned Index = 0;
4567 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4568 Index = 1;
4569
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004570 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 std::make_pair(C.kind, C.data[Index]));
4572}
4573
4574unsigned clang_isInvalid(enum CXCursorKind K) {
4575 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4576}
4577
4578unsigned clang_isDeclaration(enum CXCursorKind K) {
4579 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4580 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4581}
4582
4583unsigned clang_isReference(enum CXCursorKind K) {
4584 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4585}
4586
4587unsigned clang_isExpression(enum CXCursorKind K) {
4588 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4589}
4590
4591unsigned clang_isStatement(enum CXCursorKind K) {
4592 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4593}
4594
4595unsigned clang_isAttribute(enum CXCursorKind K) {
4596 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4597}
4598
4599unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4600 return K == CXCursor_TranslationUnit;
4601}
4602
4603unsigned clang_isPreprocessing(enum CXCursorKind K) {
4604 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4605}
4606
4607unsigned clang_isUnexposed(enum CXCursorKind K) {
4608 switch (K) {
4609 case CXCursor_UnexposedDecl:
4610 case CXCursor_UnexposedExpr:
4611 case CXCursor_UnexposedStmt:
4612 case CXCursor_UnexposedAttr:
4613 return true;
4614 default:
4615 return false;
4616 }
4617}
4618
4619CXCursorKind clang_getCursorKind(CXCursor C) {
4620 return C.kind;
4621}
4622
4623CXSourceLocation clang_getCursorLocation(CXCursor C) {
4624 if (clang_isReference(C.kind)) {
4625 switch (C.kind) {
4626 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 = getCursorObjCSuperClassRef(C);
4629 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4630 }
4631
4632 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 = getCursorObjCProtocolRef(C);
4635 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4636 }
4637
4638 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004639 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 = getCursorObjCClassRef(C);
4641 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4642 }
4643
4644 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004645 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4647 }
4648
4649 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004650 std::pair<const TemplateDecl *, SourceLocation> P =
4651 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4653 }
4654
4655 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004656 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4658 }
4659
4660 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004661 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4663 }
4664
4665 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004666 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4668 }
4669
4670 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004671 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 if (!BaseSpec)
4673 return clang_getNullLocation();
4674
4675 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4676 return cxloc::translateSourceLocation(getCursorContext(C),
4677 TSInfo->getTypeLoc().getBeginLoc());
4678
4679 return cxloc::translateSourceLocation(getCursorContext(C),
4680 BaseSpec->getLocStart());
4681 }
4682
4683 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004684 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4686 }
4687
4688 case CXCursor_OverloadedDeclRef:
4689 return cxloc::translateSourceLocation(getCursorContext(C),
4690 getCursorOverloadedDeclRef(C).second);
4691
4692 default:
4693 // FIXME: Need a way to enumerate all non-reference cases.
4694 llvm_unreachable("Missed a reference kind");
4695 }
4696 }
4697
4698 if (clang_isExpression(C.kind))
4699 return cxloc::translateSourceLocation(getCursorContext(C),
4700 getLocationFromExpr(getCursorExpr(C)));
4701
4702 if (clang_isStatement(C.kind))
4703 return cxloc::translateSourceLocation(getCursorContext(C),
4704 getCursorStmt(C)->getLocStart());
4705
4706 if (C.kind == CXCursor_PreprocessingDirective) {
4707 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4708 return cxloc::translateSourceLocation(getCursorContext(C), L);
4709 }
4710
4711 if (C.kind == CXCursor_MacroExpansion) {
4712 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004713 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 return cxloc::translateSourceLocation(getCursorContext(C), L);
4715 }
4716
4717 if (C.kind == CXCursor_MacroDefinition) {
4718 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4719 return cxloc::translateSourceLocation(getCursorContext(C), L);
4720 }
4721
4722 if (C.kind == CXCursor_InclusionDirective) {
4723 SourceLocation L
4724 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4725 return cxloc::translateSourceLocation(getCursorContext(C), L);
4726 }
4727
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004728 if (clang_isAttribute(C.kind)) {
4729 SourceLocation L
4730 = cxcursor::getCursorAttr(C)->getLocation();
4731 return cxloc::translateSourceLocation(getCursorContext(C), L);
4732 }
4733
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 if (!clang_isDeclaration(C.kind))
4735 return clang_getNullLocation();
4736
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!D)
4739 return clang_getNullLocation();
4740
4741 SourceLocation Loc = D->getLocation();
4742 // FIXME: Multiple variables declared in a single declaration
4743 // currently lack the information needed to correctly determine their
4744 // ranges when accounting for the type-specifier. We use context
4745 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4746 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004747 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 if (!cxcursor::isFirstInDeclGroup(C))
4749 Loc = VD->getLocation();
4750 }
4751
4752 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 Loc = MD->getSelectorStartLoc();
4755
4756 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4757}
4758
4759} // end extern "C"
4760
4761CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4762 assert(TU);
4763
4764 // Guard against an invalid SourceLocation, or we may assert in one
4765 // of the following calls.
4766 if (SLoc.isInvalid())
4767 return clang_getNullCursor();
4768
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004769 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004770
4771 // Translate the given source location to make it point at the beginning of
4772 // the token under the cursor.
4773 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4774 CXXUnit->getASTContext().getLangOpts());
4775
4776 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4777 if (SLoc.isValid()) {
4778 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4779 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4780 /*VisitPreprocessorLast=*/true,
4781 /*VisitIncludedEntities=*/false,
4782 SourceLocation(SLoc));
4783 CursorVis.visitFileRegion();
4784 }
4785
4786 return Result;
4787}
4788
4789static SourceRange getRawCursorExtent(CXCursor C) {
4790 if (clang_isReference(C.kind)) {
4791 switch (C.kind) {
4792 case CXCursor_ObjCSuperClassRef:
4793 return getCursorObjCSuperClassRef(C).second;
4794
4795 case CXCursor_ObjCProtocolRef:
4796 return getCursorObjCProtocolRef(C).second;
4797
4798 case CXCursor_ObjCClassRef:
4799 return getCursorObjCClassRef(C).second;
4800
4801 case CXCursor_TypeRef:
4802 return getCursorTypeRef(C).second;
4803
4804 case CXCursor_TemplateRef:
4805 return getCursorTemplateRef(C).second;
4806
4807 case CXCursor_NamespaceRef:
4808 return getCursorNamespaceRef(C).second;
4809
4810 case CXCursor_MemberRef:
4811 return getCursorMemberRef(C).second;
4812
4813 case CXCursor_CXXBaseSpecifier:
4814 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4815
4816 case CXCursor_LabelRef:
4817 return getCursorLabelRef(C).second;
4818
4819 case CXCursor_OverloadedDeclRef:
4820 return getCursorOverloadedDeclRef(C).second;
4821
4822 case CXCursor_VariableRef:
4823 return getCursorVariableRef(C).second;
4824
4825 default:
4826 // FIXME: Need a way to enumerate all non-reference cases.
4827 llvm_unreachable("Missed a reference kind");
4828 }
4829 }
4830
4831 if (clang_isExpression(C.kind))
4832 return getCursorExpr(C)->getSourceRange();
4833
4834 if (clang_isStatement(C.kind))
4835 return getCursorStmt(C)->getSourceRange();
4836
4837 if (clang_isAttribute(C.kind))
4838 return getCursorAttr(C)->getRange();
4839
4840 if (C.kind == CXCursor_PreprocessingDirective)
4841 return cxcursor::getCursorPreprocessingDirective(C);
4842
4843 if (C.kind == CXCursor_MacroExpansion) {
4844 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004845 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 return TU->mapRangeFromPreamble(Range);
4847 }
4848
4849 if (C.kind == CXCursor_MacroDefinition) {
4850 ASTUnit *TU = getCursorASTUnit(C);
4851 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4852 return TU->mapRangeFromPreamble(Range);
4853 }
4854
4855 if (C.kind == CXCursor_InclusionDirective) {
4856 ASTUnit *TU = getCursorASTUnit(C);
4857 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4858 return TU->mapRangeFromPreamble(Range);
4859 }
4860
4861 if (C.kind == CXCursor_TranslationUnit) {
4862 ASTUnit *TU = getCursorASTUnit(C);
4863 FileID MainID = TU->getSourceManager().getMainFileID();
4864 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4865 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4866 return SourceRange(Start, End);
4867 }
4868
4869 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004870 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 if (!D)
4872 return SourceRange();
4873
4874 SourceRange R = D->getSourceRange();
4875 // FIXME: Multiple variables declared in a single declaration
4876 // currently lack the information needed to correctly determine their
4877 // ranges when accounting for the type-specifier. We use context
4878 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4879 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004880 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 if (!cxcursor::isFirstInDeclGroup(C))
4882 R.setBegin(VD->getLocation());
4883 }
4884 return R;
4885 }
4886 return SourceRange();
4887}
4888
4889/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4890/// the decl-specifier-seq for declarations.
4891static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4892 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 if (!D)
4895 return SourceRange();
4896
4897 SourceRange R = D->getSourceRange();
4898
4899 // Adjust the start of the location for declarations preceded by
4900 // declaration specifiers.
4901 SourceLocation StartLoc;
4902 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4903 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4904 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4907 StartLoc = TI->getTypeLoc().getLocStart();
4908 }
4909
4910 if (StartLoc.isValid() && R.getBegin().isValid() &&
4911 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4912 R.setBegin(StartLoc);
4913
4914 // FIXME: Multiple variables declared in a single declaration
4915 // currently lack the information needed to correctly determine their
4916 // ranges when accounting for the type-specifier. We use context
4917 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4918 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (!cxcursor::isFirstInDeclGroup(C))
4921 R.setBegin(VD->getLocation());
4922 }
4923
4924 return R;
4925 }
4926
4927 return getRawCursorExtent(C);
4928}
4929
4930extern "C" {
4931
4932CXSourceRange clang_getCursorExtent(CXCursor C) {
4933 SourceRange R = getRawCursorExtent(C);
4934 if (R.isInvalid())
4935 return clang_getNullRange();
4936
4937 return cxloc::translateSourceRange(getCursorContext(C), R);
4938}
4939
4940CXCursor clang_getCursorReferenced(CXCursor C) {
4941 if (clang_isInvalid(C.kind))
4942 return clang_getNullCursor();
4943
4944 CXTranslationUnit tu = getCursorTU(C);
4945 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 if (!D)
4948 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004949 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004950 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004951 if (const ObjCPropertyImplDecl *PropImpl =
4952 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4954 return MakeCXCursor(Property, tu);
4955
4956 return C;
4957 }
4958
4959 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004960 const Expr *E = getCursorExpr(C);
4961 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 if (D) {
4963 CXCursor declCursor = MakeCXCursor(D, tu);
4964 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4965 declCursor);
4966 return declCursor;
4967 }
4968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 return MakeCursorOverloadedDeclRef(Ovl, tu);
4971
4972 return clang_getNullCursor();
4973 }
4974
4975 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004976 const Stmt *S = getCursorStmt(C);
4977 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 if (LabelDecl *label = Goto->getLabel())
4979 if (LabelStmt *labelS = label->getStmt())
4980 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4981
4982 return clang_getNullCursor();
4983 }
Richard Smith66a81862015-05-04 02:25:31 +00004984
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004986 if (const MacroDefinitionRecord *Def =
4987 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 return MakeMacroDefinitionCursor(Def, tu);
4989 }
4990
4991 if (!clang_isReference(C.kind))
4992 return clang_getNullCursor();
4993
4994 switch (C.kind) {
4995 case CXCursor_ObjCSuperClassRef:
4996 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4997
4998 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004999 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5000 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 return MakeCXCursor(Def, tu);
5002
5003 return MakeCXCursor(Prot, tu);
5004 }
5005
5006 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005007 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5008 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 return MakeCXCursor(Def, tu);
5010
5011 return MakeCXCursor(Class, tu);
5012 }
5013
5014 case CXCursor_TypeRef:
5015 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5016
5017 case CXCursor_TemplateRef:
5018 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5019
5020 case CXCursor_NamespaceRef:
5021 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5022
5023 case CXCursor_MemberRef:
5024 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5025
5026 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005027 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5029 tu ));
5030 }
5031
5032 case CXCursor_LabelRef:
5033 // FIXME: We end up faking the "parent" declaration here because we
5034 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005035 return MakeCXCursor(getCursorLabelRef(C).first,
5036 cxtu::getASTUnit(tu)->getASTContext()
5037 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 tu);
5039
5040 case CXCursor_OverloadedDeclRef:
5041 return C;
5042
5043 case CXCursor_VariableRef:
5044 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5045
5046 default:
5047 // We would prefer to enumerate all non-reference cursor kinds here.
5048 llvm_unreachable("Unhandled reference cursor kind");
5049 }
5050}
5051
5052CXCursor clang_getCursorDefinition(CXCursor C) {
5053 if (clang_isInvalid(C.kind))
5054 return clang_getNullCursor();
5055
5056 CXTranslationUnit TU = getCursorTU(C);
5057
5058 bool WasReference = false;
5059 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5060 C = clang_getCursorReferenced(C);
5061 WasReference = true;
5062 }
5063
5064 if (C.kind == CXCursor_MacroExpansion)
5065 return clang_getCursorReferenced(C);
5066
5067 if (!clang_isDeclaration(C.kind))
5068 return clang_getNullCursor();
5069
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005070 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 if (!D)
5072 return clang_getNullCursor();
5073
5074 switch (D->getKind()) {
5075 // Declaration kinds that don't really separate the notions of
5076 // declaration and definition.
5077 case Decl::Namespace:
5078 case Decl::Typedef:
5079 case Decl::TypeAlias:
5080 case Decl::TypeAliasTemplate:
5081 case Decl::TemplateTypeParm:
5082 case Decl::EnumConstant:
5083 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005084 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 case Decl::IndirectField:
5086 case Decl::ObjCIvar:
5087 case Decl::ObjCAtDefsField:
5088 case Decl::ImplicitParam:
5089 case Decl::ParmVar:
5090 case Decl::NonTypeTemplateParm:
5091 case Decl::TemplateTemplateParm:
5092 case Decl::ObjCCategoryImpl:
5093 case Decl::ObjCImplementation:
5094 case Decl::AccessSpec:
5095 case Decl::LinkageSpec:
5096 case Decl::ObjCPropertyImpl:
5097 case Decl::FileScopeAsm:
5098 case Decl::StaticAssert:
5099 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005100 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 case Decl::Label: // FIXME: Is this right??
5102 case Decl::ClassScopeFunctionSpecialization:
5103 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005104 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005105 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 return C;
5107
5108 // Declaration kinds that don't make any sense here, but are
5109 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005110 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005112 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 break;
5114
5115 // Declaration kinds for which the definition is not resolvable.
5116 case Decl::UnresolvedUsingTypename:
5117 case Decl::UnresolvedUsingValue:
5118 break;
5119
5120 case Decl::UsingDirective:
5121 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5122 TU);
5123
5124 case Decl::NamespaceAlias:
5125 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5126
5127 case Decl::Enum:
5128 case Decl::Record:
5129 case Decl::CXXRecord:
5130 case Decl::ClassTemplateSpecialization:
5131 case Decl::ClassTemplatePartialSpecialization:
5132 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5133 return MakeCXCursor(Def, TU);
5134 return clang_getNullCursor();
5135
5136 case Decl::Function:
5137 case Decl::CXXMethod:
5138 case Decl::CXXConstructor:
5139 case Decl::CXXDestructor:
5140 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005141 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005143 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 return clang_getNullCursor();
5145 }
5146
Larisse Voufo39a1e502013-08-06 01:03:05 +00005147 case Decl::Var:
5148 case Decl::VarTemplateSpecialization:
5149 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005151 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 return MakeCXCursor(Def, TU);
5153 return clang_getNullCursor();
5154 }
5155
5156 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005157 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5159 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5160 return clang_getNullCursor();
5161 }
5162
5163 case Decl::ClassTemplate: {
5164 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5165 ->getDefinition())
5166 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5167 TU);
5168 return clang_getNullCursor();
5169 }
5170
Larisse Voufo39a1e502013-08-06 01:03:05 +00005171 case Decl::VarTemplate: {
5172 if (VarDecl *Def =
5173 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5174 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5175 return clang_getNullCursor();
5176 }
5177
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case Decl::Using:
5179 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5180 D->getLocation(), TU);
5181
5182 case Decl::UsingShadow:
5183 return clang_getCursorDefinition(
5184 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5185 TU));
5186
5187 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005188 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 if (Method->isThisDeclarationADefinition())
5190 return C;
5191
5192 // Dig out the method definition in the associated
5193 // @implementation, if we have it.
5194 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005195 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5197 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5198 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5199 Method->isInstanceMethod()))
5200 if (Def->isThisDeclarationADefinition())
5201 return MakeCXCursor(Def, TU);
5202
5203 return clang_getNullCursor();
5204 }
5205
5206 case Decl::ObjCCategory:
5207 if (ObjCCategoryImplDecl *Impl
5208 = cast<ObjCCategoryDecl>(D)->getImplementation())
5209 return MakeCXCursor(Impl, TU);
5210 return clang_getNullCursor();
5211
5212 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005213 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 return MakeCXCursor(Def, TU);
5215 return clang_getNullCursor();
5216
5217 case Decl::ObjCInterface: {
5218 // There are two notions of a "definition" for an Objective-C
5219 // class: the interface and its implementation. When we resolved a
5220 // reference to an Objective-C class, produce the @interface as
5221 // the definition; when we were provided with the interface,
5222 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005223 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005225 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 return MakeCXCursor(Def, TU);
5227 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5228 return MakeCXCursor(Impl, TU);
5229 return clang_getNullCursor();
5230 }
5231
5232 case Decl::ObjCProperty:
5233 // FIXME: We don't really know where to find the
5234 // ObjCPropertyImplDecls that implement this property.
5235 return clang_getNullCursor();
5236
5237 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005238 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005240 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 return MakeCXCursor(Def, TU);
5242
5243 return clang_getNullCursor();
5244
5245 case Decl::Friend:
5246 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5247 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5248 return clang_getNullCursor();
5249
5250 case Decl::FriendTemplate:
5251 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5252 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5253 return clang_getNullCursor();
5254 }
5255
5256 return clang_getNullCursor();
5257}
5258
5259unsigned clang_isCursorDefinition(CXCursor C) {
5260 if (!clang_isDeclaration(C.kind))
5261 return 0;
5262
5263 return clang_getCursorDefinition(C) == C;
5264}
5265
5266CXCursor clang_getCanonicalCursor(CXCursor C) {
5267 if (!clang_isDeclaration(C.kind))
5268 return C;
5269
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005270 if (const Decl *D = getCursorDecl(C)) {
5271 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5273 return MakeCXCursor(CatD, getCursorTU(C));
5274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005275 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5276 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 return MakeCXCursor(IFD, getCursorTU(C));
5278
5279 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5280 }
5281
5282 return C;
5283}
5284
5285int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5286 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5287}
5288
5289unsigned clang_getNumOverloadedDecls(CXCursor C) {
5290 if (C.kind != CXCursor_OverloadedDeclRef)
5291 return 0;
5292
5293 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005294 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 return E->getNumDecls();
5296
5297 if (OverloadedTemplateStorage *S
5298 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5299 return S->size();
5300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005301 const Decl *D = Storage.get<const Decl *>();
5302 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 return Using->shadow_size();
5304
5305 return 0;
5306}
5307
5308CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5309 if (cursor.kind != CXCursor_OverloadedDeclRef)
5310 return clang_getNullCursor();
5311
5312 if (index >= clang_getNumOverloadedDecls(cursor))
5313 return clang_getNullCursor();
5314
5315 CXTranslationUnit TU = getCursorTU(cursor);
5316 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005317 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 return MakeCXCursor(E->decls_begin()[index], TU);
5319
5320 if (OverloadedTemplateStorage *S
5321 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5322 return MakeCXCursor(S->begin()[index], TU);
5323
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005324 const Decl *D = Storage.get<const Decl *>();
5325 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 // FIXME: This is, unfortunately, linear time.
5327 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5328 std::advance(Pos, index);
5329 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5330 }
5331
5332 return clang_getNullCursor();
5333}
5334
5335void clang_getDefinitionSpellingAndExtent(CXCursor C,
5336 const char **startBuf,
5337 const char **endBuf,
5338 unsigned *startLine,
5339 unsigned *startColumn,
5340 unsigned *endLine,
5341 unsigned *endColumn) {
5342 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005343 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5345
5346 SourceManager &SM = FD->getASTContext().getSourceManager();
5347 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5348 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5349 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5350 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5351 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5352 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5353}
5354
5355
5356CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5357 unsigned PieceIndex) {
5358 RefNamePieces Pieces;
5359
5360 switch (C.kind) {
5361 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005362 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5364 E->getQualifierLoc().getSourceRange());
5365 break;
5366
5367 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005368 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5370 E->getQualifierLoc().getSourceRange(),
5371 E->getOptionalExplicitTemplateArgs());
5372 break;
5373
5374 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005375 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005377 const Expr *Callee = OCE->getCallee();
5378 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 Callee = ICE->getSubExpr();
5380
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005381 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5383 DRE->getQualifierLoc().getSourceRange());
5384 }
5385 break;
5386
5387 default:
5388 break;
5389 }
5390
5391 if (Pieces.empty()) {
5392 if (PieceIndex == 0)
5393 return clang_getCursorExtent(C);
5394 } else if (PieceIndex < Pieces.size()) {
5395 SourceRange R = Pieces[PieceIndex];
5396 if (R.isValid())
5397 return cxloc::translateSourceRange(getCursorContext(C), R);
5398 }
5399
5400 return clang_getNullRange();
5401}
5402
5403void clang_enableStackTraces(void) {
5404 llvm::sys::PrintStackTraceOnErrorSignal();
5405}
5406
5407void clang_executeOnThread(void (*fn)(void*), void *user_data,
5408 unsigned stack_size) {
5409 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5410}
5411
5412} // end: extern "C"
5413
5414//===----------------------------------------------------------------------===//
5415// Token-based Operations.
5416//===----------------------------------------------------------------------===//
5417
5418/* CXToken layout:
5419 * int_data[0]: a CXTokenKind
5420 * int_data[1]: starting token location
5421 * int_data[2]: token length
5422 * int_data[3]: reserved
5423 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5424 * otherwise unused.
5425 */
5426extern "C" {
5427
5428CXTokenKind clang_getTokenKind(CXToken CXTok) {
5429 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5430}
5431
5432CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5433 switch (clang_getTokenKind(CXTok)) {
5434 case CXToken_Identifier:
5435 case CXToken_Keyword:
5436 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005437 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 ->getNameStart());
5439
5440 case CXToken_Literal: {
5441 // We have stashed the starting pointer in the ptr_data field. Use it.
5442 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005443 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 }
5445
5446 case CXToken_Punctuation:
5447 case CXToken_Comment:
5448 break;
5449 }
5450
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005451 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005452 LOG_BAD_TU(TU);
5453 return cxstring::createEmpty();
5454 }
5455
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 // We have to find the starting buffer pointer the hard way, by
5457 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005458 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005461
5462 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5463 std::pair<FileID, unsigned> LocInfo
5464 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5465 bool Invalid = false;
5466 StringRef Buffer
5467 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5468 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005469 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005470
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005471 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005472}
5473
5474CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005475 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005476 LOG_BAD_TU(TU);
5477 return clang_getNullLocation();
5478 }
5479
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005480 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 if (!CXXUnit)
5482 return clang_getNullLocation();
5483
5484 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5485 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5486}
5487
5488CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005489 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005490 LOG_BAD_TU(TU);
5491 return clang_getNullRange();
5492 }
5493
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005494 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 if (!CXXUnit)
5496 return clang_getNullRange();
5497
5498 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5499 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5500}
5501
5502static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5503 SmallVectorImpl<CXToken> &CXTokens) {
5504 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5505 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005506 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005508 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005509
5510 // Cannot tokenize across files.
5511 if (BeginLocInfo.first != EndLocInfo.first)
5512 return;
5513
5514 // Create a lexer
5515 bool Invalid = false;
5516 StringRef Buffer
5517 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5518 if (Invalid)
5519 return;
5520
5521 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5522 CXXUnit->getASTContext().getLangOpts(),
5523 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5524 Lex.SetCommentRetentionState(true);
5525
5526 // Lex tokens until we hit the end of the range.
5527 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5528 Token Tok;
5529 bool previousWasAt = false;
5530 do {
5531 // Lex the next token
5532 Lex.LexFromRawLexer(Tok);
5533 if (Tok.is(tok::eof))
5534 break;
5535
5536 // Initialize the CXToken.
5537 CXToken CXTok;
5538
5539 // - Common fields
5540 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5541 CXTok.int_data[2] = Tok.getLength();
5542 CXTok.int_data[3] = 0;
5543
5544 // - Kind-specific fields
5545 if (Tok.isLiteral()) {
5546 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005547 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 } else if (Tok.is(tok::raw_identifier)) {
5549 // Lookup the identifier to determine whether we have a keyword.
5550 IdentifierInfo *II
5551 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5552
5553 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5554 CXTok.int_data[0] = CXToken_Keyword;
5555 }
5556 else {
5557 CXTok.int_data[0] = Tok.is(tok::identifier)
5558 ? CXToken_Identifier
5559 : CXToken_Keyword;
5560 }
5561 CXTok.ptr_data = II;
5562 } else if (Tok.is(tok::comment)) {
5563 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005564 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 } else {
5566 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005567 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 }
5569 CXTokens.push_back(CXTok);
5570 previousWasAt = Tok.is(tok::at);
5571 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5572}
5573
5574void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5575 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005576 LOG_FUNC_SECTION {
5577 *Log << TU << ' ' << Range;
5578 }
5579
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005581 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 if (NumTokens)
5583 *NumTokens = 0;
5584
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005585 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005586 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005587 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005588 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005589
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005590 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 if (!CXXUnit || !Tokens || !NumTokens)
5592 return;
5593
5594 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5595
5596 SourceRange R = cxloc::translateCXSourceRange(Range);
5597 if (R.isInvalid())
5598 return;
5599
5600 SmallVector<CXToken, 32> CXTokens;
5601 getTokens(CXXUnit, R, CXTokens);
5602
5603 if (CXTokens.empty())
5604 return;
5605
5606 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5607 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5608 *NumTokens = CXTokens.size();
5609}
5610
5611void clang_disposeTokens(CXTranslationUnit TU,
5612 CXToken *Tokens, unsigned NumTokens) {
5613 free(Tokens);
5614}
5615
5616} // end: extern "C"
5617
5618//===----------------------------------------------------------------------===//
5619// Token annotation APIs.
5620//===----------------------------------------------------------------------===//
5621
Guy Benyei11169dd2012-12-18 14:30:41 +00005622static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5623 CXCursor parent,
5624 CXClientData client_data);
5625static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5626 CXClientData client_data);
5627
5628namespace {
5629class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 CXToken *Tokens;
5631 CXCursor *Cursors;
5632 unsigned NumTokens;
5633 unsigned TokIdx;
5634 unsigned PreprocessingTokIdx;
5635 CursorVisitor AnnotateVis;
5636 SourceManager &SrcMgr;
5637 bool HasContextSensitiveKeywords;
5638
5639 struct PostChildrenInfo {
5640 CXCursor Cursor;
5641 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005642 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 unsigned BeforeChildrenTokenIdx;
5644 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005645 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005646
5647 CXToken &getTok(unsigned Idx) {
5648 assert(Idx < NumTokens);
5649 return Tokens[Idx];
5650 }
5651 const CXToken &getTok(unsigned Idx) const {
5652 assert(Idx < NumTokens);
5653 return Tokens[Idx];
5654 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 bool MoreTokens() const { return TokIdx < NumTokens; }
5656 unsigned NextToken() const { return TokIdx; }
5657 void AdvanceToken() { ++TokIdx; }
5658 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005659 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 }
5661 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005662 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 }
5664 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005665 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 }
5667
5668 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005669 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 SourceRange);
5671
5672public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005674 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005677 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 AnnotateTokensVisitor, this,
5679 /*VisitPreprocessorLast=*/true,
5680 /*VisitIncludedEntities=*/false,
5681 RegionOfInterest,
5682 /*VisitDeclsOnly=*/false,
5683 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005684 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 HasContextSensitiveKeywords(false) { }
5686
5687 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5688 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5689 bool postVisitChildren(CXCursor cursor);
5690 void AnnotateTokens();
5691
5692 /// \brief Determine whether the annotator saw any cursors that have
5693 /// context-sensitive keywords.
5694 bool hasContextSensitiveKeywords() const {
5695 return HasContextSensitiveKeywords;
5696 }
5697
5698 ~AnnotateTokensWorker() {
5699 assert(PostChildrenInfos.empty());
5700 }
5701};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005702}
Guy Benyei11169dd2012-12-18 14:30:41 +00005703
5704void AnnotateTokensWorker::AnnotateTokens() {
5705 // Walk the AST within the region of interest, annotating tokens
5706 // along the way.
5707 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005708}
Guy Benyei11169dd2012-12-18 14:30:41 +00005709
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005710static inline void updateCursorAnnotation(CXCursor &Cursor,
5711 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005712 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005715}
5716
5717/// \brief It annotates and advances tokens with a cursor until the comparison
5718//// between the cursor location and the source range is the same as
5719/// \arg compResult.
5720///
5721/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5722/// Pass RangeOverlap to annotate tokens inside a range.
5723void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5724 RangeComparisonResult compResult,
5725 SourceRange range) {
5726 while (MoreTokens()) {
5727 const unsigned I = NextToken();
5728 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005729 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5730 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005731
5732 SourceLocation TokLoc = GetTokenLoc(I);
5733 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005734 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 AdvanceToken();
5736 continue;
5737 }
5738 break;
5739 }
5740}
5741
5742/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005743/// \returns true if it advanced beyond all macro tokens, false otherwise.
5744bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 CXCursor updateC,
5746 RangeComparisonResult compResult,
5747 SourceRange range) {
5748 assert(MoreTokens());
5749 assert(isFunctionMacroToken(NextToken()) &&
5750 "Should be called only for macro arg tokens");
5751
5752 // This works differently than annotateAndAdvanceTokens; because expanded
5753 // macro arguments can have arbitrary translation-unit source order, we do not
5754 // advance the token index one by one until a token fails the range test.
5755 // We only advance once past all of the macro arg tokens if all of them
5756 // pass the range test. If one of them fails we keep the token index pointing
5757 // at the start of the macro arg tokens so that the failing token will be
5758 // annotated by a subsequent annotation try.
5759
5760 bool atLeastOneCompFail = false;
5761
5762 unsigned I = NextToken();
5763 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5764 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5765 if (TokLoc.isFileID())
5766 continue; // not macro arg token, it's parens or comma.
5767 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5768 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5769 Cursors[I] = updateC;
5770 } else
5771 atLeastOneCompFail = true;
5772 }
5773
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005774 if (atLeastOneCompFail)
5775 return false;
5776
5777 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5778 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005779}
5780
5781enum CXChildVisitResult
5782AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 SourceRange cursorRange = getRawCursorExtent(cursor);
5784 if (cursorRange.isInvalid())
5785 return CXChildVisit_Recurse;
5786
5787 if (!HasContextSensitiveKeywords) {
5788 // Objective-C properties can have context-sensitive keywords.
5789 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005790 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5792 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5793 }
5794 // Objective-C methods can have context-sensitive keywords.
5795 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5796 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005797 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5799 if (Method->getObjCDeclQualifier())
5800 HasContextSensitiveKeywords = true;
5801 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005802 for (const auto *P : Method->params()) {
5803 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005804 HasContextSensitiveKeywords = true;
5805 break;
5806 }
5807 }
5808 }
5809 }
5810 }
5811 // C++ methods can have context-sensitive keywords.
5812 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005813 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5815 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5816 HasContextSensitiveKeywords = true;
5817 }
5818 }
5819 // C++ classes can have context-sensitive keywords.
5820 else if (cursor.kind == CXCursor_StructDecl ||
5821 cursor.kind == CXCursor_ClassDecl ||
5822 cursor.kind == CXCursor_ClassTemplate ||
5823 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005824 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005825 if (D->hasAttr<FinalAttr>())
5826 HasContextSensitiveKeywords = true;
5827 }
5828 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005829
5830 // Don't override a property annotation with its getter/setter method.
5831 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5832 parent.kind == CXCursor_ObjCPropertyDecl)
5833 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005834
5835 if (clang_isPreprocessing(cursor.kind)) {
5836 // Items in the preprocessing record are kept separate from items in
5837 // declarations, so we keep a separate token index.
5838 unsigned SavedTokIdx = TokIdx;
5839 TokIdx = PreprocessingTokIdx;
5840
5841 // Skip tokens up until we catch up to the beginning of the preprocessing
5842 // entry.
5843 while (MoreTokens()) {
5844 const unsigned I = NextToken();
5845 SourceLocation TokLoc = GetTokenLoc(I);
5846 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5847 case RangeBefore:
5848 AdvanceToken();
5849 continue;
5850 case RangeAfter:
5851 case RangeOverlap:
5852 break;
5853 }
5854 break;
5855 }
5856
5857 // Look at all of the tokens within this range.
5858 while (MoreTokens()) {
5859 const unsigned I = NextToken();
5860 SourceLocation TokLoc = GetTokenLoc(I);
5861 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5862 case RangeBefore:
5863 llvm_unreachable("Infeasible");
5864 case RangeAfter:
5865 break;
5866 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005867 // For macro expansions, just note where the beginning of the macro
5868 // expansion occurs.
5869 if (cursor.kind == CXCursor_MacroExpansion) {
5870 if (TokLoc == cursorRange.getBegin())
5871 Cursors[I] = cursor;
5872 AdvanceToken();
5873 break;
5874 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005875 // We may have already annotated macro names inside macro definitions.
5876 if (Cursors[I].kind != CXCursor_MacroExpansion)
5877 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 continue;
5880 }
5881 break;
5882 }
5883
5884 // Save the preprocessing token index; restore the non-preprocessing
5885 // token index.
5886 PreprocessingTokIdx = TokIdx;
5887 TokIdx = SavedTokIdx;
5888 return CXChildVisit_Recurse;
5889 }
5890
5891 if (cursorRange.isInvalid())
5892 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005893
5894 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 const enum CXCursorKind K = clang_getCursorKind(parent);
5897 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005898 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5899 // Attributes are annotated out-of-order, skip tokens until we reach it.
5900 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 ? clang_getNullCursor() : parent;
5902
5903 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5904
5905 // Avoid having the cursor of an expression "overwrite" the annotation of the
5906 // variable declaration that it belongs to.
5907 // This can happen for C++ constructor expressions whose range generally
5908 // include the variable declaration, e.g.:
5909 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005910 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005911 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005912 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 const unsigned I = NextToken();
5914 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5915 E->getLocStart() == D->getLocation() &&
5916 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005917 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 AdvanceToken();
5919 }
5920 }
5921 }
5922
5923 // Before recursing into the children keep some state that we are going
5924 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5925 // extra work after the child nodes are visited.
5926 // Note that we don't call VisitChildren here to avoid traversing statements
5927 // code-recursively which can blow the stack.
5928
5929 PostChildrenInfo Info;
5930 Info.Cursor = cursor;
5931 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005932 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 Info.BeforeChildrenTokenIdx = NextToken();
5934 PostChildrenInfos.push_back(Info);
5935
5936 return CXChildVisit_Recurse;
5937}
5938
5939bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5940 if (PostChildrenInfos.empty())
5941 return false;
5942 const PostChildrenInfo &Info = PostChildrenInfos.back();
5943 if (!clang_equalCursors(Info.Cursor, cursor))
5944 return false;
5945
5946 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5947 const unsigned AfterChildren = NextToken();
5948 SourceRange cursorRange = Info.CursorRange;
5949
5950 // Scan the tokens that are at the end of the cursor, but are not captured
5951 // but the child cursors.
5952 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5953
5954 // Scan the tokens that are at the beginning of the cursor, but are not
5955 // capture by the child cursors.
5956 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5957 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5958 break;
5959
5960 Cursors[I] = cursor;
5961 }
5962
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005963 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5964 // encountered the attribute cursor.
5965 if (clang_isAttribute(cursor.kind))
5966 TokIdx = Info.BeforeReachingCursorIdx;
5967
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 PostChildrenInfos.pop_back();
5969 return false;
5970}
5971
5972static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5973 CXCursor parent,
5974 CXClientData client_data) {
5975 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5976}
5977
5978static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5979 CXClientData client_data) {
5980 return static_cast<AnnotateTokensWorker*>(client_data)->
5981 postVisitChildren(cursor);
5982}
5983
5984namespace {
5985
5986/// \brief Uses the macro expansions in the preprocessing record to find
5987/// and mark tokens that are macro arguments. This info is used by the
5988/// AnnotateTokensWorker.
5989class MarkMacroArgTokensVisitor {
5990 SourceManager &SM;
5991 CXToken *Tokens;
5992 unsigned NumTokens;
5993 unsigned CurIdx;
5994
5995public:
5996 MarkMacroArgTokensVisitor(SourceManager &SM,
5997 CXToken *tokens, unsigned numTokens)
5998 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5999
6000 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6001 if (cursor.kind != CXCursor_MacroExpansion)
6002 return CXChildVisit_Continue;
6003
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006004 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 if (macroRange.getBegin() == macroRange.getEnd())
6006 return CXChildVisit_Continue; // it's not a function macro.
6007
6008 for (; CurIdx < NumTokens; ++CurIdx) {
6009 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6010 macroRange.getBegin()))
6011 break;
6012 }
6013
6014 if (CurIdx == NumTokens)
6015 return CXChildVisit_Break;
6016
6017 for (; CurIdx < NumTokens; ++CurIdx) {
6018 SourceLocation tokLoc = getTokenLoc(CurIdx);
6019 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6020 break;
6021
6022 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6023 }
6024
6025 if (CurIdx == NumTokens)
6026 return CXChildVisit_Break;
6027
6028 return CXChildVisit_Continue;
6029 }
6030
6031private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006032 CXToken &getTok(unsigned Idx) {
6033 assert(Idx < NumTokens);
6034 return Tokens[Idx];
6035 }
6036 const CXToken &getTok(unsigned Idx) const {
6037 assert(Idx < NumTokens);
6038 return Tokens[Idx];
6039 }
6040
Guy Benyei11169dd2012-12-18 14:30:41 +00006041 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006042 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 }
6044
6045 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6046 // The third field is reserved and currently not used. Use it here
6047 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006048 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 }
6050};
6051
6052} // end anonymous namespace
6053
6054static CXChildVisitResult
6055MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6056 CXClientData client_data) {
6057 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6058 parent);
6059}
6060
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006061/// \brief Used by \c annotatePreprocessorTokens.
6062/// \returns true if lexing was finished, false otherwise.
6063static bool lexNext(Lexer &Lex, Token &Tok,
6064 unsigned &NextIdx, unsigned NumTokens) {
6065 if (NextIdx >= NumTokens)
6066 return true;
6067
6068 ++NextIdx;
6069 Lex.LexFromRawLexer(Tok);
6070 if (Tok.is(tok::eof))
6071 return true;
6072
6073 return false;
6074}
6075
Guy Benyei11169dd2012-12-18 14:30:41 +00006076static void annotatePreprocessorTokens(CXTranslationUnit TU,
6077 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006078 CXCursor *Cursors,
6079 CXToken *Tokens,
6080 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006081 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006082
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006083 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006084 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6085 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006086 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006088 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006089
6090 if (BeginLocInfo.first != EndLocInfo.first)
6091 return;
6092
6093 StringRef Buffer;
6094 bool Invalid = false;
6095 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6096 if (Buffer.empty() || Invalid)
6097 return;
6098
6099 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6100 CXXUnit->getASTContext().getLangOpts(),
6101 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6102 Buffer.end());
6103 Lex.SetCommentRetentionState(true);
6104
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006105 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006106 // Lex tokens in raw mode until we hit the end of the range, to avoid
6107 // entering #includes or expanding macros.
6108 while (true) {
6109 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006110 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6111 break;
6112 unsigned TokIdx = NextIdx-1;
6113 assert(Tok.getLocation() ==
6114 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006115
6116 reprocess:
6117 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006118 // We have found a preprocessing directive. Annotate the tokens
6119 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 //
6121 // FIXME: Some simple tests here could identify macro definitions and
6122 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006123
6124 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006125 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6126 break;
6127
Craig Topper69186e72014-06-08 08:38:04 +00006128 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006129 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006130 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6131 break;
6132
6133 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006134 IdentifierInfo &II =
6135 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006136 SourceLocation MappedTokLoc =
6137 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6138 MI = getMacroInfo(II, MappedTokLoc, TU);
6139 }
6140 }
6141
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006142 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006144 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6145 finished = true;
6146 break;
6147 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006148 // If we are in a macro definition, check if the token was ever a
6149 // macro name and annotate it if that's the case.
6150 if (MI) {
6151 SourceLocation SaveLoc = Tok.getLocation();
6152 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006153 MacroDefinitionRecord *MacroDef =
6154 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006155 Tok.setLocation(SaveLoc);
6156 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006157 Cursors[NextIdx - 1] =
6158 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006159 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006160 } while (!Tok.isAtStartOfLine());
6161
6162 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6163 assert(TokIdx <= LastIdx);
6164 SourceLocation EndLoc =
6165 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6166 CXCursor Cursor =
6167 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6168
6169 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006170 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006171
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006172 if (finished)
6173 break;
6174 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 }
6177}
6178
6179// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006180static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6181 CXToken *Tokens, unsigned NumTokens,
6182 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006183 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6185 setThreadBackgroundPriority();
6186
6187 // Determine the region of interest, which contains all of the tokens.
6188 SourceRange RegionOfInterest;
6189 RegionOfInterest.setBegin(
6190 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6191 RegionOfInterest.setEnd(
6192 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6193 Tokens[NumTokens-1])));
6194
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 // Relex the tokens within the source range to look for preprocessing
6196 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006198
6199 // If begin location points inside a macro argument, set it to the expansion
6200 // location so we can have the full context when annotating semantically.
6201 {
6202 SourceManager &SM = CXXUnit->getSourceManager();
6203 SourceLocation Loc =
6204 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6205 if (Loc.isMacroID())
6206 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6207 }
6208
Guy Benyei11169dd2012-12-18 14:30:41 +00006209 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6210 // Search and mark tokens that are macro argument expansions.
6211 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6212 Tokens, NumTokens);
6213 CursorVisitor MacroArgMarker(TU,
6214 MarkMacroArgTokensVisitorDelegate, &Visitor,
6215 /*VisitPreprocessorLast=*/true,
6216 /*VisitIncludedEntities=*/false,
6217 RegionOfInterest);
6218 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6219 }
6220
6221 // Annotate all of the source locations in the region of interest that map to
6222 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006223 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006224
6225 // FIXME: We use a ridiculous stack size here because the data-recursion
6226 // algorithm uses a large stack frame than the non-data recursive version,
6227 // and AnnotationTokensWorker currently transforms the data-recursion
6228 // algorithm back into a traditional recursion by explicitly calling
6229 // VisitChildren(). We will need to remove this explicit recursive call.
6230 W.AnnotateTokens();
6231
6232 // If we ran into any entities that involve context-sensitive keywords,
6233 // take another pass through the tokens to mark them as such.
6234 if (W.hasContextSensitiveKeywords()) {
6235 for (unsigned I = 0; I != NumTokens; ++I) {
6236 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6237 continue;
6238
6239 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6240 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006241 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6243 if (Property->getPropertyAttributesAsWritten() != 0 &&
6244 llvm::StringSwitch<bool>(II->getName())
6245 .Case("readonly", true)
6246 .Case("assign", true)
6247 .Case("unsafe_unretained", true)
6248 .Case("readwrite", true)
6249 .Case("retain", true)
6250 .Case("copy", true)
6251 .Case("nonatomic", true)
6252 .Case("atomic", true)
6253 .Case("getter", true)
6254 .Case("setter", true)
6255 .Case("strong", true)
6256 .Case("weak", true)
6257 .Default(false))
6258 Tokens[I].int_data[0] = CXToken_Keyword;
6259 }
6260 continue;
6261 }
6262
6263 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6264 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6265 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6266 if (llvm::StringSwitch<bool>(II->getName())
6267 .Case("in", true)
6268 .Case("out", true)
6269 .Case("inout", true)
6270 .Case("oneway", true)
6271 .Case("bycopy", true)
6272 .Case("byref", true)
6273 .Default(false))
6274 Tokens[I].int_data[0] = CXToken_Keyword;
6275 continue;
6276 }
6277
6278 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6279 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6280 Tokens[I].int_data[0] = CXToken_Keyword;
6281 continue;
6282 }
6283 }
6284 }
6285}
6286
6287extern "C" {
6288
6289void clang_annotateTokens(CXTranslationUnit TU,
6290 CXToken *Tokens, unsigned NumTokens,
6291 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006292 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006293 LOG_BAD_TU(TU);
6294 return;
6295 }
6296 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006297 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006298 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006299 }
6300
6301 LOG_FUNC_SECTION {
6302 *Log << TU << ' ';
6303 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6304 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6305 *Log << clang_getRange(bloc, eloc);
6306 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006307
6308 // Any token we don't specifically annotate will have a NULL cursor.
6309 CXCursor C = clang_getNullCursor();
6310 for (unsigned I = 0; I != NumTokens; ++I)
6311 Cursors[I] = C;
6312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006314 if (!CXXUnit)
6315 return;
6316
6317 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006318
6319 auto AnnotateTokensImpl = [=]() {
6320 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6321 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006322 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006323 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6325 }
6326}
6327
6328} // end: extern "C"
6329
6330//===----------------------------------------------------------------------===//
6331// Operations for querying linkage of a cursor.
6332//===----------------------------------------------------------------------===//
6333
6334extern "C" {
6335CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6336 if (!clang_isDeclaration(cursor.kind))
6337 return CXLinkage_Invalid;
6338
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006339 const Decl *D = cxcursor::getCursorDecl(cursor);
6340 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006341 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006342 case NoLinkage:
6343 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 case InternalLinkage: return CXLinkage_Internal;
6345 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6346 case ExternalLinkage: return CXLinkage_External;
6347 };
6348
6349 return CXLinkage_Invalid;
6350}
6351} // end: extern "C"
6352
6353//===----------------------------------------------------------------------===//
6354// Operations for querying language of a cursor.
6355//===----------------------------------------------------------------------===//
6356
6357static CXLanguageKind getDeclLanguage(const Decl *D) {
6358 if (!D)
6359 return CXLanguage_C;
6360
6361 switch (D->getKind()) {
6362 default:
6363 break;
6364 case Decl::ImplicitParam:
6365 case Decl::ObjCAtDefsField:
6366 case Decl::ObjCCategory:
6367 case Decl::ObjCCategoryImpl:
6368 case Decl::ObjCCompatibleAlias:
6369 case Decl::ObjCImplementation:
6370 case Decl::ObjCInterface:
6371 case Decl::ObjCIvar:
6372 case Decl::ObjCMethod:
6373 case Decl::ObjCProperty:
6374 case Decl::ObjCPropertyImpl:
6375 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006376 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006377 return CXLanguage_ObjC;
6378 case Decl::CXXConstructor:
6379 case Decl::CXXConversion:
6380 case Decl::CXXDestructor:
6381 case Decl::CXXMethod:
6382 case Decl::CXXRecord:
6383 case Decl::ClassTemplate:
6384 case Decl::ClassTemplatePartialSpecialization:
6385 case Decl::ClassTemplateSpecialization:
6386 case Decl::Friend:
6387 case Decl::FriendTemplate:
6388 case Decl::FunctionTemplate:
6389 case Decl::LinkageSpec:
6390 case Decl::Namespace:
6391 case Decl::NamespaceAlias:
6392 case Decl::NonTypeTemplateParm:
6393 case Decl::StaticAssert:
6394 case Decl::TemplateTemplateParm:
6395 case Decl::TemplateTypeParm:
6396 case Decl::UnresolvedUsingTypename:
6397 case Decl::UnresolvedUsingValue:
6398 case Decl::Using:
6399 case Decl::UsingDirective:
6400 case Decl::UsingShadow:
6401 return CXLanguage_CPlusPlus;
6402 }
6403
6404 return CXLanguage_C;
6405}
6406
6407extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006408
6409static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6410 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006411 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006412
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006413 switch (D->getAvailability()) {
6414 case AR_Available:
6415 case AR_NotYetIntroduced:
6416 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006417 return getCursorAvailabilityForDecl(
6418 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006419 return CXAvailability_Available;
6420
6421 case AR_Deprecated:
6422 return CXAvailability_Deprecated;
6423
6424 case AR_Unavailable:
6425 return CXAvailability_NotAvailable;
6426 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006427
6428 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006429}
6430
Guy Benyei11169dd2012-12-18 14:30:41 +00006431enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6432 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006433 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6434 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006435
6436 return CXAvailability_Available;
6437}
6438
6439static CXVersion convertVersion(VersionTuple In) {
6440 CXVersion Out = { -1, -1, -1 };
6441 if (In.empty())
6442 return Out;
6443
6444 Out.Major = In.getMajor();
6445
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006446 Optional<unsigned> Minor = In.getMinor();
6447 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 Out.Minor = *Minor;
6449 else
6450 return Out;
6451
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006452 Optional<unsigned> Subminor = In.getSubminor();
6453 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 Out.Subminor = *Subminor;
6455
6456 return Out;
6457}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006458
6459static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6460 int *always_deprecated,
6461 CXString *deprecated_message,
6462 int *always_unavailable,
6463 CXString *unavailable_message,
6464 CXPlatformAvailability *availability,
6465 int availability_size) {
6466 bool HadAvailAttr = false;
6467 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006468 for (auto A : D->attrs()) {
6469 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006470 HadAvailAttr = true;
6471 if (always_deprecated)
6472 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006473 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006474 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006475 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006476 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006477 continue;
6478 }
6479
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006480 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 HadAvailAttr = true;
6482 if (always_unavailable)
6483 *always_unavailable = 1;
6484 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006485 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006486 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6487 }
6488 continue;
6489 }
6490
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006491 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006492 HadAvailAttr = true;
6493 if (N < availability_size) {
6494 availability[N].Platform
6495 = cxstring::createDup(Avail->getPlatform()->getName());
6496 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6497 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6498 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6499 availability[N].Unavailable = Avail->getUnavailable();
6500 availability[N].Message = cxstring::createDup(Avail->getMessage());
6501 }
6502 ++N;
6503 }
6504 }
6505
6506 if (!HadAvailAttr)
6507 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6508 return getCursorPlatformAvailabilityForDecl(
6509 cast<Decl>(EnumConst->getDeclContext()),
6510 always_deprecated,
6511 deprecated_message,
6512 always_unavailable,
6513 unavailable_message,
6514 availability,
6515 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006516
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006517 return N;
6518}
6519
Guy Benyei11169dd2012-12-18 14:30:41 +00006520int clang_getCursorPlatformAvailability(CXCursor cursor,
6521 int *always_deprecated,
6522 CXString *deprecated_message,
6523 int *always_unavailable,
6524 CXString *unavailable_message,
6525 CXPlatformAvailability *availability,
6526 int availability_size) {
6527 if (always_deprecated)
6528 *always_deprecated = 0;
6529 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006530 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 if (always_unavailable)
6532 *always_unavailable = 0;
6533 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006534 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006535
Guy Benyei11169dd2012-12-18 14:30:41 +00006536 if (!clang_isDeclaration(cursor.kind))
6537 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006538
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006539 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 if (!D)
6541 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006542
6543 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6544 deprecated_message,
6545 always_unavailable,
6546 unavailable_message,
6547 availability,
6548 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006549}
6550
6551void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6552 clang_disposeString(availability->Platform);
6553 clang_disposeString(availability->Message);
6554}
6555
6556CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6557 if (clang_isDeclaration(cursor.kind))
6558 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6559
6560 return CXLanguage_Invalid;
6561}
6562
6563 /// \brief If the given cursor is the "templated" declaration
6564 /// descibing a class or function template, return the class or
6565 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006566static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006567 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006568 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006570 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6572 return FunTmpl;
6573
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006574 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6576 return ClassTmpl;
6577
6578 return D;
6579}
6580
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006581
6582enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6583 StorageClass sc = SC_None;
6584 const Decl *D = getCursorDecl(C);
6585 if (D) {
6586 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6587 sc = FD->getStorageClass();
6588 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6589 sc = VD->getStorageClass();
6590 } else {
6591 return CX_SC_Invalid;
6592 }
6593 } else {
6594 return CX_SC_Invalid;
6595 }
6596 switch (sc) {
6597 case SC_None:
6598 return CX_SC_None;
6599 case SC_Extern:
6600 return CX_SC_Extern;
6601 case SC_Static:
6602 return CX_SC_Static;
6603 case SC_PrivateExtern:
6604 return CX_SC_PrivateExtern;
6605 case SC_OpenCLWorkGroupLocal:
6606 return CX_SC_OpenCLWorkGroupLocal;
6607 case SC_Auto:
6608 return CX_SC_Auto;
6609 case SC_Register:
6610 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006611 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006612 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006613}
6614
Guy Benyei11169dd2012-12-18 14:30:41 +00006615CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6616 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006617 if (const Decl *D = getCursorDecl(cursor)) {
6618 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 if (!DC)
6620 return clang_getNullCursor();
6621
6622 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6623 getCursorTU(cursor));
6624 }
6625 }
6626
6627 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006628 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 return MakeCXCursor(D, getCursorTU(cursor));
6630 }
6631
6632 return clang_getNullCursor();
6633}
6634
6635CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6636 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006637 if (const Decl *D = getCursorDecl(cursor)) {
6638 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 if (!DC)
6640 return clang_getNullCursor();
6641
6642 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6643 getCursorTU(cursor));
6644 }
6645 }
6646
6647 // FIXME: Note that we can't easily compute the lexical context of a
6648 // statement or expression, so we return nothing.
6649 return clang_getNullCursor();
6650}
6651
6652CXFile clang_getIncludedFile(CXCursor cursor) {
6653 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006654 return nullptr;
6655
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006656 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006657 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006658}
6659
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006660unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6661 if (C.kind != CXCursor_ObjCPropertyDecl)
6662 return CXObjCPropertyAttr_noattr;
6663
6664 unsigned Result = CXObjCPropertyAttr_noattr;
6665 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6666 ObjCPropertyDecl::PropertyAttributeKind Attr =
6667 PD->getPropertyAttributesAsWritten();
6668
6669#define SET_CXOBJCPROP_ATTR(A) \
6670 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6671 Result |= CXObjCPropertyAttr_##A
6672 SET_CXOBJCPROP_ATTR(readonly);
6673 SET_CXOBJCPROP_ATTR(getter);
6674 SET_CXOBJCPROP_ATTR(assign);
6675 SET_CXOBJCPROP_ATTR(readwrite);
6676 SET_CXOBJCPROP_ATTR(retain);
6677 SET_CXOBJCPROP_ATTR(copy);
6678 SET_CXOBJCPROP_ATTR(nonatomic);
6679 SET_CXOBJCPROP_ATTR(setter);
6680 SET_CXOBJCPROP_ATTR(atomic);
6681 SET_CXOBJCPROP_ATTR(weak);
6682 SET_CXOBJCPROP_ATTR(strong);
6683 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6684#undef SET_CXOBJCPROP_ATTR
6685
6686 return Result;
6687}
6688
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006689unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6690 if (!clang_isDeclaration(C.kind))
6691 return CXObjCDeclQualifier_None;
6692
6693 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6694 const Decl *D = getCursorDecl(C);
6695 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6696 QT = MD->getObjCDeclQualifier();
6697 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6698 QT = PD->getObjCDeclQualifier();
6699 if (QT == Decl::OBJC_TQ_None)
6700 return CXObjCDeclQualifier_None;
6701
6702 unsigned Result = CXObjCDeclQualifier_None;
6703 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6704 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6705 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6706 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6707 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6708 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6709
6710 return Result;
6711}
6712
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006713unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6714 if (!clang_isDeclaration(C.kind))
6715 return 0;
6716
6717 const Decl *D = getCursorDecl(C);
6718 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6719 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6720 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6721 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6722
6723 return 0;
6724}
6725
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006726unsigned clang_Cursor_isVariadic(CXCursor C) {
6727 if (!clang_isDeclaration(C.kind))
6728 return 0;
6729
6730 const Decl *D = getCursorDecl(C);
6731 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6732 return FD->isVariadic();
6733 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6734 return MD->isVariadic();
6735
6736 return 0;
6737}
6738
Guy Benyei11169dd2012-12-18 14:30:41 +00006739CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6740 if (!clang_isDeclaration(C.kind))
6741 return clang_getNullRange();
6742
6743 const Decl *D = getCursorDecl(C);
6744 ASTContext &Context = getCursorContext(C);
6745 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6746 if (!RC)
6747 return clang_getNullRange();
6748
6749 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6750}
6751
6752CXString clang_Cursor_getRawCommentText(CXCursor C) {
6753 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006754 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006755
6756 const Decl *D = getCursorDecl(C);
6757 ASTContext &Context = getCursorContext(C);
6758 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6759 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6760 StringRef();
6761
6762 // Don't duplicate the string because RawText points directly into source
6763 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006764 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006765}
6766
6767CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6768 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006769 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006770
6771 const Decl *D = getCursorDecl(C);
6772 const ASTContext &Context = getCursorContext(C);
6773 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6774
6775 if (RC) {
6776 StringRef BriefText = RC->getBriefText(Context);
6777
6778 // Don't duplicate the string because RawComment ensures that this memory
6779 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006780 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 }
6782
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006783 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006784}
6785
Guy Benyei11169dd2012-12-18 14:30:41 +00006786CXModule clang_Cursor_getModule(CXCursor C) {
6787 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006788 if (const ImportDecl *ImportD =
6789 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006790 return ImportD->getImportedModule();
6791 }
6792
Craig Topper69186e72014-06-08 08:38:04 +00006793 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006794}
6795
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006796CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6797 if (isNotUsableTU(TU)) {
6798 LOG_BAD_TU(TU);
6799 return nullptr;
6800 }
6801 if (!File)
6802 return nullptr;
6803 FileEntry *FE = static_cast<FileEntry *>(File);
6804
6805 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6806 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6807 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6808
Richard Smithfeb54b62014-10-23 02:01:19 +00006809 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006810}
6811
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006812CXFile clang_Module_getASTFile(CXModule CXMod) {
6813 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006814 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006815 Module *Mod = static_cast<Module*>(CXMod);
6816 return const_cast<FileEntry *>(Mod->getASTFile());
6817}
6818
Guy Benyei11169dd2012-12-18 14:30:41 +00006819CXModule clang_Module_getParent(CXModule CXMod) {
6820 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006821 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006822 Module *Mod = static_cast<Module*>(CXMod);
6823 return Mod->Parent;
6824}
6825
6826CXString clang_Module_getName(CXModule CXMod) {
6827 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006828 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006829 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006830 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006831}
6832
6833CXString clang_Module_getFullName(CXModule CXMod) {
6834 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006835 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006836 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006837 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006838}
6839
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006840int clang_Module_isSystem(CXModule CXMod) {
6841 if (!CXMod)
6842 return 0;
6843 Module *Mod = static_cast<Module*>(CXMod);
6844 return Mod->IsSystem;
6845}
6846
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006847unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6848 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006849 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006850 LOG_BAD_TU(TU);
6851 return 0;
6852 }
6853 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 return 0;
6855 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006856 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6857 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6858 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006859}
6860
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006861CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6862 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006863 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006864 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006866 }
6867 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006870 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006871
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006872 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6873 if (Index < TopHeaders.size())
6874 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006875
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006877}
6878
6879} // end: extern "C"
6880
6881//===----------------------------------------------------------------------===//
6882// C++ AST instrospection.
6883//===----------------------------------------------------------------------===//
6884
6885extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006886unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6887 if (!clang_isDeclaration(C.kind))
6888 return 0;
6889
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006890 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006891 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006892 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006893 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6894}
6895
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006896unsigned clang_CXXMethod_isConst(CXCursor C) {
6897 if (!clang_isDeclaration(C.kind))
6898 return 0;
6899
6900 const Decl *D = cxcursor::getCursorDecl(C);
6901 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006902 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006903 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6904}
6905
Guy Benyei11169dd2012-12-18 14:30:41 +00006906unsigned clang_CXXMethod_isStatic(CXCursor C) {
6907 if (!clang_isDeclaration(C.kind))
6908 return 0;
6909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006910 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006911 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006912 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006913 return (Method && Method->isStatic()) ? 1 : 0;
6914}
6915
6916unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6917 if (!clang_isDeclaration(C.kind))
6918 return 0;
6919
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006920 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006921 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006922 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 return (Method && Method->isVirtual()) ? 1 : 0;
6924}
6925} // end: extern "C"
6926
6927//===----------------------------------------------------------------------===//
6928// Attribute introspection.
6929//===----------------------------------------------------------------------===//
6930
6931extern "C" {
6932CXType clang_getIBOutletCollectionType(CXCursor C) {
6933 if (C.kind != CXCursor_IBOutletCollectionAttr)
6934 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6935
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006936 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006937 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6938
6939 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6940}
6941} // end: extern "C"
6942
6943//===----------------------------------------------------------------------===//
6944// Inspecting memory usage.
6945//===----------------------------------------------------------------------===//
6946
6947typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6948
6949static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6950 enum CXTUResourceUsageKind k,
6951 unsigned long amount) {
6952 CXTUResourceUsageEntry entry = { k, amount };
6953 entries.push_back(entry);
6954}
6955
6956extern "C" {
6957
6958const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6959 const char *str = "";
6960 switch (kind) {
6961 case CXTUResourceUsage_AST:
6962 str = "ASTContext: expressions, declarations, and types";
6963 break;
6964 case CXTUResourceUsage_Identifiers:
6965 str = "ASTContext: identifiers";
6966 break;
6967 case CXTUResourceUsage_Selectors:
6968 str = "ASTContext: selectors";
6969 break;
6970 case CXTUResourceUsage_GlobalCompletionResults:
6971 str = "Code completion: cached global results";
6972 break;
6973 case CXTUResourceUsage_SourceManagerContentCache:
6974 str = "SourceManager: content cache allocator";
6975 break;
6976 case CXTUResourceUsage_AST_SideTables:
6977 str = "ASTContext: side tables";
6978 break;
6979 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6980 str = "SourceManager: malloc'ed memory buffers";
6981 break;
6982 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6983 str = "SourceManager: mmap'ed memory buffers";
6984 break;
6985 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6986 str = "ExternalASTSource: malloc'ed memory buffers";
6987 break;
6988 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6989 str = "ExternalASTSource: mmap'ed memory buffers";
6990 break;
6991 case CXTUResourceUsage_Preprocessor:
6992 str = "Preprocessor: malloc'ed memory";
6993 break;
6994 case CXTUResourceUsage_PreprocessingRecord:
6995 str = "Preprocessor: PreprocessingRecord";
6996 break;
6997 case CXTUResourceUsage_SourceManager_DataStructures:
6998 str = "SourceManager: data structures and tables";
6999 break;
7000 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7001 str = "Preprocessor: header search tables";
7002 break;
7003 }
7004 return str;
7005}
7006
7007CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007008 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007009 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007010 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 return usage;
7012 }
7013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007014 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007015 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007016 ASTContext &astContext = astUnit->getASTContext();
7017
7018 // How much memory is used by AST nodes and types?
7019 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7020 (unsigned long) astContext.getASTAllocatedMemory());
7021
7022 // How much memory is used by identifiers?
7023 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7024 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7025
7026 // How much memory is used for selectors?
7027 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7028 (unsigned long) astContext.Selectors.getTotalMemory());
7029
7030 // How much memory is used by ASTContext's side tables?
7031 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7032 (unsigned long) astContext.getSideTableAllocatedMemory());
7033
7034 // How much memory is used for caching global code completion results?
7035 unsigned long completionBytes = 0;
7036 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007037 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007038 completionBytes = completionAllocator->getTotalMemory();
7039 }
7040 createCXTUResourceUsageEntry(*entries,
7041 CXTUResourceUsage_GlobalCompletionResults,
7042 completionBytes);
7043
7044 // How much memory is being used by SourceManager's content cache?
7045 createCXTUResourceUsageEntry(*entries,
7046 CXTUResourceUsage_SourceManagerContentCache,
7047 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7048
7049 // How much memory is being used by the MemoryBuffer's in SourceManager?
7050 const SourceManager::MemoryBufferSizes &srcBufs =
7051 astUnit->getSourceManager().getMemoryBufferSizes();
7052
7053 createCXTUResourceUsageEntry(*entries,
7054 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7055 (unsigned long) srcBufs.malloc_bytes);
7056 createCXTUResourceUsageEntry(*entries,
7057 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7058 (unsigned long) srcBufs.mmap_bytes);
7059 createCXTUResourceUsageEntry(*entries,
7060 CXTUResourceUsage_SourceManager_DataStructures,
7061 (unsigned long) astContext.getSourceManager()
7062 .getDataStructureSizes());
7063
7064 // How much memory is being used by the ExternalASTSource?
7065 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7066 const ExternalASTSource::MemoryBufferSizes &sizes =
7067 esrc->getMemoryBufferSizes();
7068
7069 createCXTUResourceUsageEntry(*entries,
7070 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7071 (unsigned long) sizes.malloc_bytes);
7072 createCXTUResourceUsageEntry(*entries,
7073 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7074 (unsigned long) sizes.mmap_bytes);
7075 }
7076
7077 // How much memory is being used by the Preprocessor?
7078 Preprocessor &pp = astUnit->getPreprocessor();
7079 createCXTUResourceUsageEntry(*entries,
7080 CXTUResourceUsage_Preprocessor,
7081 pp.getTotalMemory());
7082
7083 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7084 createCXTUResourceUsageEntry(*entries,
7085 CXTUResourceUsage_PreprocessingRecord,
7086 pRec->getTotalMemory());
7087 }
7088
7089 createCXTUResourceUsageEntry(*entries,
7090 CXTUResourceUsage_Preprocessor_HeaderSearch,
7091 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007092
Guy Benyei11169dd2012-12-18 14:30:41 +00007093 CXTUResourceUsage usage = { (void*) entries.get(),
7094 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007095 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007096 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007097 return usage;
7098}
7099
7100void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7101 if (usage.data)
7102 delete (MemUsageEntries*) usage.data;
7103}
7104
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007105CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7106 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007107 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007108 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007109
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007110 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007111 LOG_BAD_TU(TU);
7112 return skipped;
7113 }
7114
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007115 if (!file)
7116 return skipped;
7117
7118 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7119 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7120 if (!ppRec)
7121 return skipped;
7122
7123 ASTContext &Ctx = astUnit->getASTContext();
7124 SourceManager &sm = Ctx.getSourceManager();
7125 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7126 FileID wantedFileID = sm.translateFile(fileEntry);
7127
7128 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7129 std::vector<SourceRange> wantedRanges;
7130 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7131 i != ei; ++i) {
7132 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7133 wantedRanges.push_back(*i);
7134 }
7135
7136 skipped->count = wantedRanges.size();
7137 skipped->ranges = new CXSourceRange[skipped->count];
7138 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7139 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7140
7141 return skipped;
7142}
7143
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007144void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7145 if (ranges) {
7146 delete[] ranges->ranges;
7147 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007148 }
7149}
7150
Guy Benyei11169dd2012-12-18 14:30:41 +00007151} // end extern "C"
7152
7153void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7154 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7155 for (unsigned I = 0; I != Usage.numEntries; ++I)
7156 fprintf(stderr, " %s: %lu\n",
7157 clang_getTUResourceUsageName(Usage.entries[I].kind),
7158 Usage.entries[I].amount);
7159
7160 clang_disposeCXTUResourceUsage(Usage);
7161}
7162
7163//===----------------------------------------------------------------------===//
7164// Misc. utility functions.
7165//===----------------------------------------------------------------------===//
7166
7167/// Default to using an 8 MB stack size on "safety" threads.
7168static unsigned SafetyStackThreadSize = 8 << 20;
7169
7170namespace clang {
7171
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007172bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007173 unsigned Size) {
7174 if (!Size)
7175 Size = GetSafetyThreadStackSize();
7176 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007177 return CRC.RunSafelyOnThread(Fn, Size);
7178 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007179}
7180
7181unsigned GetSafetyThreadStackSize() {
7182 return SafetyStackThreadSize;
7183}
7184
7185void SetSafetyThreadStackSize(unsigned Value) {
7186 SafetyStackThreadSize = Value;
7187}
7188
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007189}
Guy Benyei11169dd2012-12-18 14:30:41 +00007190
7191void clang::setThreadBackgroundPriority() {
7192 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7193 return;
7194
Alp Toker1a86ad22014-07-06 06:24:00 +00007195#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007196 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7197#endif
7198}
7199
7200void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7201 if (!Unit)
7202 return;
7203
7204 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7205 DEnd = Unit->stored_diag_end();
7206 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007207 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007208 CXString Msg = clang_formatDiagnostic(&Diag,
7209 clang_defaultDiagnosticDisplayOptions());
7210 fprintf(stderr, "%s\n", clang_getCString(Msg));
7211 clang_disposeString(Msg);
7212 }
7213#ifdef LLVM_ON_WIN32
7214 // On Windows, force a flush, since there may be multiple copies of
7215 // stderr and stdout in the file system, all with different buffers
7216 // but writing to the same device.
7217 fflush(stderr);
7218#endif
7219}
7220
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007221MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7222 SourceLocation MacroDefLoc,
7223 CXTranslationUnit TU){
7224 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007225 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007226 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007227 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007228
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007229 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007230 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007231 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007232 if (MD) {
7233 for (MacroDirective::DefInfo
7234 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7235 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7236 return Def.getMacroInfo();
7237 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007238 }
7239
Craig Topper69186e72014-06-08 08:38:04 +00007240 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241}
7242
Richard Smith66a81862015-05-04 02:25:31 +00007243const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007244 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007245 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007246 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007247 const IdentifierInfo *II = MacroDef->getName();
7248 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007249 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007250
7251 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7252}
7253
Richard Smith66a81862015-05-04 02:25:31 +00007254MacroDefinitionRecord *
7255cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7256 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007258 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007259 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007260 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261
7262 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007263 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7265 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007266 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007267
7268 // Check that the token is inside the definition and not its argument list.
7269 SourceManager &SM = Unit->getSourceManager();
7270 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007271 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007272 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007273 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007274
7275 Preprocessor &PP = Unit->getPreprocessor();
7276 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7277 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007278 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007279
Alp Toker2d57cea2014-05-17 04:53:25 +00007280 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007281 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283
7284 // Check that the identifier is not one of the macro arguments.
7285 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007286 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007287
Richard Smith20e883e2015-04-29 23:20:19 +00007288 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007289 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007290 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007291
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007292 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007293}
7294
Richard Smith66a81862015-05-04 02:25:31 +00007295MacroDefinitionRecord *
7296cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7297 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007298 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007299 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007300
7301 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007302 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007303 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007304 Preprocessor &PP = Unit->getPreprocessor();
7305 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007306 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007307 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7308 Token Tok;
7309 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007310 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007311
7312 return checkForMacroInMacroDefinition(MI, Tok, TU);
7313}
7314
Guy Benyei11169dd2012-12-18 14:30:41 +00007315extern "C" {
7316
7317CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007318 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007319}
7320
7321} // end: extern "C"
7322
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007323Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7324 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007325 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007326 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007327 if (Unit->isMainFileAST())
7328 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329 return *this;
7330 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007331 } else {
7332 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007333 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007334 return *this;
7335}
7336
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007337Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7338 *this << FE->getName();
7339 return *this;
7340}
7341
7342Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7343 CXString cursorName = clang_getCursorDisplayName(cursor);
7344 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7345 clang_disposeString(cursorName);
7346 return *this;
7347}
7348
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007349Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7350 CXFile File;
7351 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007352 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007353 CXString FileName = clang_getFileName(File);
7354 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7355 clang_disposeString(FileName);
7356 return *this;
7357}
7358
7359Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7360 CXSourceLocation BLoc = clang_getRangeStart(range);
7361 CXSourceLocation ELoc = clang_getRangeEnd(range);
7362
7363 CXFile BFile;
7364 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007365 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007366
7367 CXFile EFile;
7368 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007369 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007370
7371 CXString BFileName = clang_getFileName(BFile);
7372 if (BFile == EFile) {
7373 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7374 BLine, BColumn, ELine, EColumn);
7375 } else {
7376 CXString EFileName = clang_getFileName(EFile);
7377 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7378 BLine, BColumn)
7379 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7380 ELine, EColumn);
7381 clang_disposeString(EFileName);
7382 }
7383 clang_disposeString(BFileName);
7384 return *this;
7385}
7386
7387Logger &cxindex::Logger::operator<<(CXString Str) {
7388 *this << clang_getCString(Str);
7389 return *this;
7390}
7391
7392Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7393 LogOS << Fmt;
7394 return *this;
7395}
7396
Chandler Carruth37ad2582014-06-27 15:14:39 +00007397static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7398
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007399cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007400 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007401
7402 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7403
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007404 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007405 OS << "[libclang:" << Name << ':';
7406
Alp Toker1a86ad22014-07-06 06:24:00 +00007407#ifdef USE_DARWIN_THREADS
7408 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007409 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7410 OS << tid << ':';
7411#endif
7412
7413 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7414 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007415 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007416
7417 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007418 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007419 OS << "--------------------------------------------------\n";
7420 }
7421}