blob: cbba64a431a409fe48d4b25c7ad3dfb6dfaf5669 [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:
1463 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001464 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001465 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001466#define BUILTIN_TYPE(Id, SingletonId)
1467#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1468#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1469#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1470#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1471#include "clang/AST/BuiltinTypes.def"
1472 break;
1473
1474 case BuiltinType::ObjCId:
1475 VisitType = Context.getObjCIdType();
1476 break;
1477
1478 case BuiltinType::ObjCClass:
1479 VisitType = Context.getObjCClassType();
1480 break;
1481
1482 case BuiltinType::ObjCSel:
1483 VisitType = Context.getObjCSelType();
1484 break;
1485 }
1486
1487 if (!VisitType.isNull()) {
1488 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1489 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1490 TU));
1491 }
1492
1493 return false;
1494}
1495
1496bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1497 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1498}
1499
1500bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1501 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1502}
1503
1504bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1505 if (TL.isDefinition())
1506 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1507
1508 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1509}
1510
1511bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1512 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1513}
1514
1515bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1516 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1517 return true;
1518
1519 return false;
1520}
1521
1522bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1523 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1524 return true;
1525
Douglas Gregore9d95f12015-07-07 03:57:35 +00001526 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1527 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1528 return true;
1529 }
1530
Guy Benyei11169dd2012-12-18 14:30:41 +00001531 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1532 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1533 TU)))
1534 return true;
1535 }
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1541 return Visit(TL.getPointeeLoc());
1542}
1543
1544bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1545 return Visit(TL.getInnerLoc());
1546}
1547
1548bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1549 return Visit(TL.getPointeeLoc());
1550}
1551
1552bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1553 return Visit(TL.getPointeeLoc());
1554}
1555
1556bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1557 return Visit(TL.getPointeeLoc());
1558}
1559
1560bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1561 return Visit(TL.getPointeeLoc());
1562}
1563
1564bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1565 return Visit(TL.getPointeeLoc());
1566}
1567
1568bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1569 return Visit(TL.getModifiedLoc());
1570}
1571
1572bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1573 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001574 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001575 return true;
1576
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001577 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1578 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001579 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1580 return true;
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1586 if (Visit(TL.getElementLoc()))
1587 return true;
1588
1589 if (Expr *Size = TL.getSizeExpr())
1590 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1591
1592 return false;
1593}
1594
Reid Kleckner8a365022013-06-24 17:51:48 +00001595bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1596 return Visit(TL.getOriginalLoc());
1597}
1598
Reid Kleckner0503a872013-12-05 01:23:43 +00001599bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1600 return Visit(TL.getOriginalLoc());
1601}
1602
Guy Benyei11169dd2012-12-18 14:30:41 +00001603bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1604 TemplateSpecializationTypeLoc TL) {
1605 // Visit the template name.
1606 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1607 TL.getTemplateNameLoc()))
1608 return true;
1609
1610 // Visit the template arguments.
1611 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1612 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1613 return true;
1614
1615 return false;
1616}
1617
1618bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1619 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1620}
1621
1622bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1623 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1624 return Visit(TSInfo->getTypeLoc());
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1630 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1631 return Visit(TSInfo->getTypeLoc());
1632
1633 return false;
1634}
1635
1636bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1637 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1638 return true;
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1644 DependentTemplateSpecializationTypeLoc TL) {
1645 // Visit the nested-name-specifier, if there is one.
1646 if (TL.getQualifierLoc() &&
1647 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1648 return true;
1649
1650 // Visit the template arguments.
1651 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1652 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1653 return true;
1654
1655 return false;
1656}
1657
1658bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1659 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1660 return true;
1661
1662 return Visit(TL.getNamedTypeLoc());
1663}
1664
1665bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1666 return Visit(TL.getPatternLoc());
1667}
1668
1669bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1670 if (Expr *E = TL.getUnderlyingExpr())
1671 return Visit(MakeCXCursor(E, StmtParent, TU));
1672
1673 return false;
1674}
1675
1676bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1677 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1678}
1679
1680bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1681 return Visit(TL.getValueLoc());
1682}
1683
1684#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1685bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1686 return Visit##PARENT##Loc(TL); \
1687}
1688
1689DEFAULT_TYPELOC_IMPL(Complex, Type)
1690DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1691DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1692DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1693DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1694DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1695DEFAULT_TYPELOC_IMPL(Vector, Type)
1696DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1697DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1698DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1699DEFAULT_TYPELOC_IMPL(Record, TagType)
1700DEFAULT_TYPELOC_IMPL(Enum, TagType)
1701DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1702DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1703DEFAULT_TYPELOC_IMPL(Auto, Type)
1704
1705bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1706 // Visit the nested-name-specifier, if present.
1707 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1708 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1709 return true;
1710
1711 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001712 for (const auto &I : D->bases()) {
1713 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 return true;
1715 }
1716 }
1717
1718 return VisitTagDecl(D);
1719}
1720
1721bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001722 for (const auto *I : D->attrs())
1723 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 return true;
1725
1726 return false;
1727}
1728
1729//===----------------------------------------------------------------------===//
1730// Data-recursive visitor methods.
1731//===----------------------------------------------------------------------===//
1732
1733namespace {
1734#define DEF_JOB(NAME, DATA, KIND)\
1735class NAME : public VisitorJob {\
1736public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001737 NAME(const DATA *d, CXCursor parent) : \
1738 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001739 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001740 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001741};
1742
1743DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1744DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1745DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1746DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1747DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1748 ExplicitTemplateArgsVisitKind)
1749DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1750DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1751DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1752#undef DEF_JOB
1753
1754class DeclVisit : public VisitorJob {
1755public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001756 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001758 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001759 static bool classof(const VisitorJob *VJ) {
1760 return VJ->getKind() == DeclVisitKind;
1761 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001763 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001764};
1765class TypeLocVisit : public VisitorJob {
1766public:
1767 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1768 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1769 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1770
1771 static bool classof(const VisitorJob *VJ) {
1772 return VJ->getKind() == TypeLocVisitKind;
1773 }
1774
1775 TypeLoc get() const {
1776 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 }
1779};
1780
1781class LabelRefVisit : public VisitorJob {
1782public:
1783 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1784 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1785 labelLoc.getPtrEncoding()) {}
1786
1787 static bool classof(const VisitorJob *VJ) {
1788 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1789 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001790 const LabelDecl *get() const {
1791 return static_cast<const LabelDecl *>(data[0]);
1792 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 SourceLocation getLoc() const {
1794 return SourceLocation::getFromPtrEncoding(data[1]); }
1795};
1796
1797class NestedNameSpecifierLocVisit : public VisitorJob {
1798public:
1799 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1800 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1801 Qualifier.getNestedNameSpecifier(),
1802 Qualifier.getOpaqueData()) { }
1803
1804 static bool classof(const VisitorJob *VJ) {
1805 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1806 }
1807
1808 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 return NestedNameSpecifierLoc(
1810 const_cast<NestedNameSpecifier *>(
1811 static_cast<const NestedNameSpecifier *>(data[0])),
1812 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 }
1814};
1815
1816class DeclarationNameInfoVisit : public VisitorJob {
1817public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001818 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001819 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001820 static bool classof(const VisitorJob *VJ) {
1821 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1822 }
1823 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001824 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001825 switch (S->getStmtClass()) {
1826 default:
1827 llvm_unreachable("Unhandled Stmt");
1828 case clang::Stmt::MSDependentExistsStmtClass:
1829 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1830 case Stmt::CXXDependentScopeMemberExprClass:
1831 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1832 case Stmt::DependentScopeDeclRefExprClass:
1833 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001834 case Stmt::OMPCriticalDirectiveClass:
1835 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 }
1837 }
1838};
1839class MemberRefVisit : public VisitorJob {
1840public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001841 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001842 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1843 L.getPtrEncoding()) {}
1844 static bool classof(const VisitorJob *VJ) {
1845 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1846 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 const FieldDecl *get() const {
1848 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001849 }
1850 SourceLocation getLoc() const {
1851 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1852 }
1853};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001855 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001856 VisitorWorkList &WL;
1857 CXCursor Parent;
1858public:
1859 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1860 : WL(wl), Parent(parent) {}
1861
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1863 void VisitBlockExpr(const BlockExpr *B);
1864 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1865 void VisitCompoundStmt(const CompoundStmt *S);
1866 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1867 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1868 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1869 void VisitCXXNewExpr(const CXXNewExpr *E);
1870 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1871 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1872 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1873 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1874 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1875 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1876 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1877 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001878 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void VisitDeclRefExpr(const DeclRefExpr *D);
1880 void VisitDeclStmt(const DeclStmt *S);
1881 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1882 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1883 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1884 void VisitForStmt(const ForStmt *FS);
1885 void VisitGotoStmt(const GotoStmt *GS);
1886 void VisitIfStmt(const IfStmt *If);
1887 void VisitInitListExpr(const InitListExpr *IE);
1888 void VisitMemberExpr(const MemberExpr *M);
1889 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1890 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1891 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1892 void VisitOverloadExpr(const OverloadExpr *E);
1893 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1894 void VisitStmt(const Stmt *S);
1895 void VisitSwitchStmt(const SwitchStmt *S);
1896 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1898 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1899 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1900 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1901 void VisitVAArgExpr(const VAArgExpr *E);
1902 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1903 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1904 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1905 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001906 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001907 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001908 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001909 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001910 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001911 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001912 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001913 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001914 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001915 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001916 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001917 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001918 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001919 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001920 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001921 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001922 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001923 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001924 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001925 void
1926 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001927 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001928 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001929 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001930 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001931 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001932 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001933 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934
Guy Benyei11169dd2012-12-18 14:30:41 +00001935private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1938 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001939 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1940 void AddStmt(const Stmt *S);
1941 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001942 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001943 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001945};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001946} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001947
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 // 'S' should always be non-null, since it comes from the
1950 // statement we are visiting.
1951 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1952}
1953
1954void
1955EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1956 if (Qualifier)
1957 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1958}
1959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001961 if (S)
1962 WL.push_back(StmtVisit(S, Parent));
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 if (D)
1966 WL.push_back(DeclVisit(D, Parent, isFirst));
1967}
1968void EnqueueVisitor::
1969 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1970 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001972}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 if (D)
1975 WL.push_back(MemberRefVisit(D, L, Parent));
1976}
1977void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1978 if (TI)
1979 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1980 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001983 for (const Stmt *SubStmt : S->children()) {
1984 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 }
1986 if (size == WL.size())
1987 return;
1988 // Now reverse the entries we just added. This will match the DFS
1989 // ordering performed by the worklist.
1990 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1991 std::reverse(I, E);
1992}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001993namespace {
1994class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1995 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001996 /// \brief Process clauses with list of variables.
1997 template <typename T>
1998 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001999public:
2000 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2001#define OPENMP_CLAUSE(Name, Class) \
2002 void Visit##Class(const Class *C);
2003#include "clang/Basic/OpenMPKinds.def"
2004};
2005
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002006void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2007 Visitor->AddStmt(C->getCondition());
2008}
2009
Alexey Bataev3778b602014-07-17 07:32:53 +00002010void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2011 Visitor->AddStmt(C->getCondition());
2012}
2013
Alexey Bataev568a8332014-03-06 06:15:19 +00002014void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2015 Visitor->AddStmt(C->getNumThreads());
2016}
2017
Alexey Bataev62c87d22014-03-21 04:51:18 +00002018void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2019 Visitor->AddStmt(C->getSafelen());
2020}
2021
Alexey Bataev66b15b52015-08-21 11:14:16 +00002022void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2023 Visitor->AddStmt(C->getSimdlen());
2024}
2025
Alexander Musman8bd31e62014-05-27 15:12:19 +00002026void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2027 Visitor->AddStmt(C->getNumForLoops());
2028}
2029
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002030void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002031
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002032void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2033
Alexey Bataev56dafe82014-06-20 07:16:17 +00002034void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2035 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002036 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002037}
2038
Alexey Bataev10e775f2015-07-30 11:36:16 +00002039void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2040 Visitor->AddStmt(C->getNumForLoops());
2041}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002042
Alexey Bataev236070f2014-06-20 11:19:47 +00002043void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2044
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002045void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2046
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002047void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2048
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002049void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2050
Alexey Bataevdea47612014-07-23 07:46:59 +00002051void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2052
Alexey Bataev67a4f222014-07-23 10:25:33 +00002053void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2054
Alexey Bataev459dec02014-07-24 06:46:57 +00002055void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2056
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002057void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2058
Michael Wonge710d542015-08-07 16:16:36 +00002059void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2060 Visitor->AddStmt(C->getDevice());
2061}
2062
Alexey Bataev756c1962013-09-24 03:17:45 +00002063template<typename T>
2064void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002065 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002066 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002067 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002068}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002069
2070void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002071 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002072 for (const auto *E : C->private_copies()) {
2073 Visitor->AddStmt(E);
2074 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002075}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002076void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2077 const OMPFirstprivateClause *C) {
2078 VisitOMPClauseList(C);
2079}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002080void OMPClauseEnqueue::VisitOMPLastprivateClause(
2081 const OMPLastprivateClause *C) {
2082 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002083 for (auto *E : C->private_copies()) {
2084 Visitor->AddStmt(E);
2085 }
2086 for (auto *E : C->source_exprs()) {
2087 Visitor->AddStmt(E);
2088 }
2089 for (auto *E : C->destination_exprs()) {
2090 Visitor->AddStmt(E);
2091 }
2092 for (auto *E : C->assignment_ops()) {
2093 Visitor->AddStmt(E);
2094 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002095}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002096void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002097 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002098}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002099void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2100 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002101 for (auto *E : C->lhs_exprs()) {
2102 Visitor->AddStmt(E);
2103 }
2104 for (auto *E : C->rhs_exprs()) {
2105 Visitor->AddStmt(E);
2106 }
2107 for (auto *E : C->reduction_ops()) {
2108 Visitor->AddStmt(E);
2109 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002110}
Alexander Musman8dba6642014-04-22 13:09:42 +00002111void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2112 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002113 for (const auto *E : C->privates()) {
2114 Visitor->AddStmt(E);
2115 }
Alexander Musman3276a272015-03-21 10:12:56 +00002116 for (const auto *E : C->inits()) {
2117 Visitor->AddStmt(E);
2118 }
2119 for (const auto *E : C->updates()) {
2120 Visitor->AddStmt(E);
2121 }
2122 for (const auto *E : C->finals()) {
2123 Visitor->AddStmt(E);
2124 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002125 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002126 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002127}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002128void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2129 VisitOMPClauseList(C);
2130 Visitor->AddStmt(C->getAlignment());
2131}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002132void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2133 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002134 for (auto *E : C->source_exprs()) {
2135 Visitor->AddStmt(E);
2136 }
2137 for (auto *E : C->destination_exprs()) {
2138 Visitor->AddStmt(E);
2139 }
2140 for (auto *E : C->assignment_ops()) {
2141 Visitor->AddStmt(E);
2142 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002143}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002144void
2145OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2146 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002147 for (auto *E : C->source_exprs()) {
2148 Visitor->AddStmt(E);
2149 }
2150 for (auto *E : C->destination_exprs()) {
2151 Visitor->AddStmt(E);
2152 }
2153 for (auto *E : C->assignment_ops()) {
2154 Visitor->AddStmt(E);
2155 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002156}
Alexey Bataev6125da92014-07-21 11:26:11 +00002157void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2158 VisitOMPClauseList(C);
2159}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002160void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2161 VisitOMPClauseList(C);
2162}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002163}
Alexey Bataev756c1962013-09-24 03:17:45 +00002164
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002165void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2166 unsigned size = WL.size();
2167 OMPClauseEnqueue Visitor(this);
2168 Visitor.Visit(S);
2169 if (size == WL.size())
2170 return;
2171 // Now reverse the entries we just added. This will match the DFS
2172 // ordering performed by the worklist.
2173 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2174 std::reverse(I, E);
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddDecl(B->getBlockDecl());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(E);
2184 AddTypeLoc(E->getTypeSourceInfo());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002187 for (auto &I : llvm::reverse(S->body()))
2188 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002189}
2190void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(S->getSubStmt());
2193 AddDeclarationNameInfo(S);
2194 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2195 AddNestedNameSpecifierLoc(QualifierLoc);
2196}
2197
2198void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2201 AddDeclarationNameInfo(E);
2202 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2203 AddNestedNameSpecifierLoc(QualifierLoc);
2204 if (!E->isImplicitAccess())
2205 AddStmt(E->getBase());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 // Enqueue the initializer , if any.
2209 AddStmt(E->getInitializer());
2210 // Enqueue the array size, if any.
2211 AddStmt(E->getArraySize());
2212 // Enqueue the allocated type.
2213 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2214 // Enqueue the placement arguments.
2215 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2216 AddStmt(E->getPlacementArg(I-1));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2220 AddStmt(CE->getArg(I-1));
2221 AddStmt(CE->getCallee());
2222 AddStmt(CE->getArg(0));
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2225 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // Visit the name of the type being destroyed.
2227 AddTypeLoc(E->getDestroyedTypeInfo());
2228 // Visit the scope type that looks disturbingly like the nested-name-specifier
2229 // but isn't.
2230 AddTypeLoc(E->getScopeTypeInfo());
2231 // Visit the nested-name-specifier.
2232 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2233 AddNestedNameSpecifierLoc(QualifierLoc);
2234 // Visit base expression.
2235 AddStmt(E->getBase());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2238 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddTypeLoc(E->getTypeSourceInfo());
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2242 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 EnqueueChildren(E);
2244 AddTypeLoc(E->getTypeSourceInfo());
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(E);
2248 if (E->isTypeOperand())
2249 AddTypeLoc(E->getTypeOperandSourceInfo());
2250}
2251
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2253 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 AddTypeLoc(E->getTypeSourceInfo());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueChildren(E);
2259 if (E->isTypeOperand())
2260 AddTypeLoc(E->getTypeOperandSourceInfo());
2261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 EnqueueChildren(S);
2265 AddDecl(S->getExceptionDecl());
2266}
2267
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002268void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002269 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002270 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002271 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 if (DR->hasExplicitTemplateArgs()) {
2276 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2277 }
2278 WL.push_back(DeclRefExprParts(DR, Parent));
2279}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2281 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2283 AddDeclarationNameInfo(E);
2284 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 unsigned size = WL.size();
2288 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002289 for (const auto *D : S->decls()) {
2290 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 isFirst = false;
2292 }
2293 if (size == WL.size())
2294 return;
2295 // Now reverse the entries we just added. This will match the DFS
2296 // ordering performed by the worklist.
2297 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2298 std::reverse(I, E);
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 D = E->designators_rbegin(), DEnd = E->designators_rend();
2304 D != DEnd; ++D) {
2305 if (D->isFieldDesignator()) {
2306 if (FieldDecl *Field = D->getField())
2307 AddMemberRef(Field, D->getFieldLoc());
2308 continue;
2309 }
2310 if (D->isArrayDesignator()) {
2311 AddStmt(E->getArrayIndex(*D));
2312 continue;
2313 }
2314 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2315 AddStmt(E->getArrayRangeEnd(*D));
2316 AddStmt(E->getArrayRangeStart(*D));
2317 }
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 EnqueueChildren(E);
2321 AddTypeLoc(E->getTypeInfoAsWritten());
2322}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 AddStmt(FS->getBody());
2325 AddStmt(FS->getInc());
2326 AddStmt(FS->getCond());
2327 AddDecl(FS->getConditionVariable());
2328 AddStmt(FS->getInit());
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 AddStmt(If->getElse());
2335 AddStmt(If->getThen());
2336 AddStmt(If->getCond());
2337 AddDecl(If->getConditionVariable());
2338}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 // We care about the syntactic form of the initializer list, only.
2341 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2342 IE = Syntactic;
2343 EnqueueChildren(IE);
2344}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 WL.push_back(MemberExprParts(M, Parent));
2347
2348 // If the base of the member access expression is an implicit 'this', don't
2349 // visit it.
2350 // FIXME: If we ever want to show these implicit accesses, this will be
2351 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002352 if (M->isImplicitAccess())
2353 return;
2354
2355 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2356 // real field that that we are interested in.
2357 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2358 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2359 if (FD->isAnonymousStructOrUnion()) {
2360 AddStmt(SubME->getBase());
2361 return;
2362 }
2363 }
2364 }
2365
2366 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddTypeLoc(E->getEncodedTypeSourceInfo());
2370}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 EnqueueChildren(M);
2373 AddTypeLoc(M->getClassReceiverTypeInfo());
2374}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 // Visit the components of the offsetof expression.
2377 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2378 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2379 const OffsetOfNode &Node = E->getComponent(I-1);
2380 switch (Node.getKind()) {
2381 case OffsetOfNode::Array:
2382 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2383 break;
2384 case OffsetOfNode::Field:
2385 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2386 break;
2387 case OffsetOfNode::Identifier:
2388 case OffsetOfNode::Base:
2389 continue;
2390 }
2391 }
2392 // Visit the type into which we're computing the offset.
2393 AddTypeLoc(E->getTypeSourceInfo());
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2397 WL.push_back(OverloadExprParts(E, Parent));
2398}
2399void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueChildren(E);
2402 if (E->isArgumentType())
2403 AddTypeLoc(E->getArgumentTypeInfo());
2404}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002405void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 EnqueueChildren(S);
2407}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 AddStmt(S->getBody());
2410 AddStmt(S->getCond());
2411 AddDecl(S->getConditionVariable());
2412}
2413
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 AddStmt(W->getBody());
2416 AddStmt(W->getCond());
2417 AddDecl(W->getConditionVariable());
2418}
2419
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 for (unsigned I = E->getNumArgs(); I > 0; --I)
2422 AddTypeLoc(E->getArg(I-1));
2423}
2424
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 AddTypeLoc(E->getQueriedTypeSourceInfo());
2427}
2428
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 EnqueueChildren(E);
2431}
2432
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 VisitOverloadExpr(U);
2435 if (!U->isImplicitAccess())
2436 AddStmt(U->getBase());
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 AddStmt(E->getSubExpr());
2440 AddTypeLoc(E->getWrittenTypeInfo());
2441}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 WL.push_back(SizeOfPackExprParts(E, Parent));
2444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 // If the opaque value has a source expression, just transparently
2447 // visit that. This is useful for (e.g.) pseudo-object expressions.
2448 if (Expr *SourceExpr = E->getSourceExpr())
2449 return Visit(SourceExpr);
2450}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 AddStmt(E->getBody());
2453 WL.push_back(LambdaExprParts(E, Parent));
2454}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 // Treat the expression like its syntactic form.
2457 Visit(E->getSyntacticForm());
2458}
2459
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002460void EnqueueVisitor::VisitOMPExecutableDirective(
2461 const OMPExecutableDirective *D) {
2462 EnqueueChildren(D);
2463 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2464 E = D->clauses().end();
2465 I != E; ++I)
2466 EnqueueChildren(*I);
2467}
2468
Alexander Musman3aaab662014-08-19 11:27:13 +00002469void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2470 VisitOMPExecutableDirective(D);
2471}
2472
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002473void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2474 VisitOMPExecutableDirective(D);
2475}
2476
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002477void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002478 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002479}
2480
Alexey Bataevf29276e2014-06-18 04:14:57 +00002481void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002482 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002483}
2484
Alexander Musmanf82886e2014-09-18 05:12:34 +00002485void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2486 VisitOMPLoopDirective(D);
2487}
2488
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002489void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2490 VisitOMPExecutableDirective(D);
2491}
2492
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002493void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2494 VisitOMPExecutableDirective(D);
2495}
2496
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002497void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Alexander Musman80c22892014-07-17 08:54:58 +00002501void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503}
2504
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002505void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2506 VisitOMPExecutableDirective(D);
2507 AddDeclarationNameInfo(D);
2508}
2509
Alexey Bataev4acb8592014-07-07 13:01:15 +00002510void
2511EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002512 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002513}
2514
Alexander Musmane4e893b2014-09-23 09:33:00 +00002515void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2516 const OMPParallelForSimdDirective *D) {
2517 VisitOMPLoopDirective(D);
2518}
2519
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002520void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2521 const OMPParallelSectionsDirective *D) {
2522 VisitOMPExecutableDirective(D);
2523}
2524
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002525void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2526 VisitOMPExecutableDirective(D);
2527}
2528
Alexey Bataev68446b72014-07-18 07:47:19 +00002529void
2530EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002534void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataev2df347a2014-07-18 10:17:07 +00002538void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002542void EnqueueVisitor::VisitOMPTaskgroupDirective(
2543 const OMPTaskgroupDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataev6125da92014-07-21 11:26:11 +00002547void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2548 VisitOMPExecutableDirective(D);
2549}
2550
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002551void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev0162e452014-07-22 10:10:35 +00002555void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002559void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Michael Wong65f367f2015-07-21 13:44:28 +00002563void EnqueueVisitor::VisitOMPTargetDataDirective(const
2564 OMPTargetDataDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev13314bf2014-10-09 04:18:56 +00002568void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002572void EnqueueVisitor::VisitOMPCancellationPointDirective(
2573 const OMPCancellationPointDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexey Bataev80909872015-07-02 11:25:17 +00002577void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579}
2580
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002581void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2583}
2584
2585bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2586 if (RegionOfInterest.isValid()) {
2587 SourceRange Range = getRawCursorExtent(C);
2588 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2589 return false;
2590 }
2591 return true;
2592}
2593
2594bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2595 while (!WL.empty()) {
2596 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002597 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598
2599 // Set the Parent field, then back to its old value once we're done.
2600 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2601
2602 switch (LI.getKind()) {
2603 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 if (!D)
2606 continue;
2607
2608 // For now, perform default visitation for Decls.
2609 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2610 cast<DeclVisit>(&LI)->isFirst())))
2611 return true;
2612
2613 continue;
2614 }
2615 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2616 const ASTTemplateArgumentListInfo *ArgList =
2617 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2618 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2619 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2620 Arg != ArgEnd; ++Arg) {
2621 if (VisitTemplateArgumentLoc(*Arg))
2622 return true;
2623 }
2624 continue;
2625 }
2626 case VisitorJob::TypeLocVisitKind: {
2627 // Perform default visitation for TypeLocs.
2628 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2629 return true;
2630 continue;
2631 }
2632 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 if (LabelStmt *stmt = LS->getStmt()) {
2635 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2636 TU))) {
2637 return true;
2638 }
2639 }
2640 continue;
2641 }
2642
2643 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2644 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2645 if (VisitNestedNameSpecifierLoc(V->get()))
2646 return true;
2647 continue;
2648 }
2649
2650 case VisitorJob::DeclarationNameInfoVisitKind: {
2651 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2652 ->get()))
2653 return true;
2654 continue;
2655 }
2656 case VisitorJob::MemberRefVisitKind: {
2657 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2658 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2659 return true;
2660 continue;
2661 }
2662 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002663 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 if (!S)
2665 continue;
2666
2667 // Update the current cursor.
2668 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2669 if (!IsInRegionOfInterest(Cursor))
2670 continue;
2671 switch (Visitor(Cursor, Parent, ClientData)) {
2672 case CXChildVisit_Break: return true;
2673 case CXChildVisit_Continue: break;
2674 case CXChildVisit_Recurse:
2675 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002676 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 EnqueueWorkList(WL, S);
2678 break;
2679 }
2680 continue;
2681 }
2682 case VisitorJob::MemberExprPartsKind: {
2683 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002684 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002685
2686 // Visit the nested-name-specifier
2687 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2688 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2689 return true;
2690
2691 // Visit the declaration name.
2692 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2693 return true;
2694
2695 // Visit the explicitly-specified template arguments, if any.
2696 if (M->hasExplicitTemplateArgs()) {
2697 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2698 *ArgEnd = Arg + M->getNumTemplateArgs();
2699 Arg != ArgEnd; ++Arg) {
2700 if (VisitTemplateArgumentLoc(*Arg))
2701 return true;
2702 }
2703 }
2704 continue;
2705 }
2706 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002707 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 // Visit nested-name-specifier, if present.
2709 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2710 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2711 return true;
2712 // Visit declaration name.
2713 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2714 return true;
2715 continue;
2716 }
2717 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 // Visit the nested-name-specifier.
2720 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2721 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2722 return true;
2723 // Visit the declaration name.
2724 if (VisitDeclarationNameInfo(O->getNameInfo()))
2725 return true;
2726 // Visit the overloaded declaration reference.
2727 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2728 return true;
2729 continue;
2730 }
2731 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 NamedDecl *Pack = E->getPack();
2734 if (isa<TemplateTypeParmDecl>(Pack)) {
2735 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2736 E->getPackLoc(), TU)))
2737 return true;
2738
2739 continue;
2740 }
2741
2742 if (isa<TemplateTemplateParmDecl>(Pack)) {
2743 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2744 E->getPackLoc(), TU)))
2745 return true;
2746
2747 continue;
2748 }
2749
2750 // Non-type template parameter packs and function parameter packs are
2751 // treated like DeclRefExpr cursors.
2752 continue;
2753 }
2754
2755 case VisitorJob::LambdaExprPartsKind: {
2756 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002757 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2759 CEnd = E->explicit_capture_end();
2760 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002761 // FIXME: Lambda init-captures.
2762 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002763 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002764
Guy Benyei11169dd2012-12-18 14:30:41 +00002765 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2766 C->getLocation(),
2767 TU)))
2768 return true;
2769 }
2770
2771 // Visit parameters and return type, if present.
2772 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2773 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2774 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2775 // Visit the whole type.
2776 if (Visit(TL))
2777 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002778 } else if (FunctionProtoTypeLoc Proto =
2779 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002780 if (E->hasExplicitParameters()) {
2781 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002782 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2783 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 return true;
2785 } else {
2786 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002787 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 return true;
2789 }
2790 }
2791 }
2792 break;
2793 }
2794
2795 case VisitorJob::PostChildrenVisitKind:
2796 if (PostChildrenVisitor(Parent, ClientData))
2797 return true;
2798 break;
2799 }
2800 }
2801 return false;
2802}
2803
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002804bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002805 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 if (!WorkListFreeList.empty()) {
2807 WL = WorkListFreeList.back();
2808 WL->clear();
2809 WorkListFreeList.pop_back();
2810 }
2811 else {
2812 WL = new VisitorWorkList();
2813 WorkListCache.push_back(WL);
2814 }
2815 EnqueueWorkList(*WL, S);
2816 bool result = RunVisitorWorkList(*WL);
2817 WorkListFreeList.push_back(WL);
2818 return result;
2819}
2820
2821namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002822typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002823RefNamePieces
2824buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2825 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2826 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2828 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2829 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2830
2831 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2832
2833 RefNamePieces Pieces;
2834
2835 if (WantQualifier && QLoc.isValid())
2836 Pieces.push_back(QLoc);
2837
2838 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2839 Pieces.push_back(NI.getLoc());
2840
2841 if (WantTemplateArgs && TemplateArgs)
2842 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2843 TemplateArgs->RAngleLoc));
2844
2845 if (Kind == DeclarationName::CXXOperatorName) {
2846 Pieces.push_back(SourceLocation::getFromRawEncoding(
2847 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2848 Pieces.push_back(SourceLocation::getFromRawEncoding(
2849 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2850 }
2851
2852 if (WantSinglePiece) {
2853 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2854 Pieces.clear();
2855 Pieces.push_back(R);
2856 }
2857
2858 return Pieces;
2859}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002860}
Guy Benyei11169dd2012-12-18 14:30:41 +00002861
2862//===----------------------------------------------------------------------===//
2863// Misc. API hooks.
2864//===----------------------------------------------------------------------===//
2865
Chad Rosier05c71aa2013-03-27 18:28:23 +00002866static void fatal_error_handler(void *user_data, const std::string& reason,
2867 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002868 // Write the result out to stderr avoiding errs() because raw_ostreams can
2869 // call report_fatal_error.
2870 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2871 ::abort();
2872}
2873
Chandler Carruth66660742014-06-27 16:37:27 +00002874namespace {
2875struct RegisterFatalErrorHandler {
2876 RegisterFatalErrorHandler() {
2877 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2878 }
2879};
2880}
2881
2882static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2883
Guy Benyei11169dd2012-12-18 14:30:41 +00002884extern "C" {
2885CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2886 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 // We use crash recovery to make some of our APIs more reliable, implicitly
2888 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002889 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2890 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002891
Chandler Carruth66660742014-06-27 16:37:27 +00002892 // Look through the managed static to trigger construction of the managed
2893 // static which registers our fatal error handler. This ensures it is only
2894 // registered once.
2895 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002896
Adrian Prantlbc068582015-07-08 01:00:30 +00002897 // Initialize targets for clang module support.
2898 llvm::InitializeAllTargets();
2899 llvm::InitializeAllTargetMCs();
2900 llvm::InitializeAllAsmPrinters();
2901 llvm::InitializeAllAsmParsers();
2902
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002903 CIndexer *CIdxr = new CIndexer();
2904
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (excludeDeclarationsFromPCH)
2906 CIdxr->setOnlyLocalDecls();
2907 if (displayDiagnostics)
2908 CIdxr->setDisplayDiagnostics();
2909
2910 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2911 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2912 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2913 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2914 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2915 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2916
2917 return CIdxr;
2918}
2919
2920void clang_disposeIndex(CXIndex CIdx) {
2921 if (CIdx)
2922 delete static_cast<CIndexer *>(CIdx);
2923}
2924
2925void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2926 if (CIdx)
2927 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2928}
2929
2930unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2931 if (CIdx)
2932 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2933 return 0;
2934}
2935
2936void clang_toggleCrashRecovery(unsigned isEnabled) {
2937 if (isEnabled)
2938 llvm::CrashRecoveryContext::Enable();
2939 else
2940 llvm::CrashRecoveryContext::Disable();
2941}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002942
Guy Benyei11169dd2012-12-18 14:30:41 +00002943CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2944 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002945 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002946 enum CXErrorCode Result =
2947 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002948 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002949 assert((TU && Result == CXError_Success) ||
2950 (!TU && Result != CXError_Success));
2951 return TU;
2952}
2953
2954enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2955 const char *ast_filename,
2956 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002957 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002958 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002959
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960 if (!CIdx || !ast_filename || !out_TU)
2961 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002963 LOG_FUNC_SECTION {
2964 *Log << ast_filename;
2965 }
2966
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2968 FileSystemOptions FileSystemOpts;
2969
Justin Bognerd512c1e2014-10-15 00:33:06 +00002970 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2971 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002972 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002973 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002974 FileSystemOpts, /*UseDebugInfo=*/false,
2975 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002976 /*CaptureDiagnostics=*/true,
2977 /*AllowPCHWithCompilerErrors=*/true,
2978 /*UserFilesAreVolatile=*/true);
2979 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002981}
2982
2983unsigned clang_defaultEditingTranslationUnitOptions() {
2984 return CXTranslationUnit_PrecompiledPreamble |
2985 CXTranslationUnit_CacheCompletionResults;
2986}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987
Guy Benyei11169dd2012-12-18 14:30:41 +00002988CXTranslationUnit
2989clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2990 const char *source_filename,
2991 int num_command_line_args,
2992 const char * const *command_line_args,
2993 unsigned num_unsaved_files,
2994 struct CXUnsavedFile *unsaved_files) {
2995 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2996 return clang_parseTranslationUnit(CIdx, source_filename,
2997 command_line_args, num_command_line_args,
2998 unsaved_files, num_unsaved_files,
2999 Options);
3000}
3001
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003002static CXErrorCode
3003clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3004 const char *const *command_line_args,
3005 int num_command_line_args,
3006 ArrayRef<CXUnsavedFile> unsaved_files,
3007 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003008 // Set up the initial return values.
3009 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003010 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003011
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003013 if (!CIdx || !out_TU)
3014 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3017
3018 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3019 setThreadBackgroundPriority();
3020
3021 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3022 // FIXME: Add a flag for modules.
3023 TranslationUnitKind TUKind
3024 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003025 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003026 = options & CXTranslationUnit_CacheCompletionResults;
3027 bool IncludeBriefCommentsInCodeCompletion
3028 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3029 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3030 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3031
3032 // Configure the diagnostics.
3033 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003034 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003035
3036 // Recover resources if we crash before exiting this function.
3037 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3038 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003039 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003040
Ahmed Charlesb8984322014-03-07 20:03:18 +00003041 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3042 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003043
3044 // Recover resources if we crash before exiting this function.
3045 llvm::CrashRecoveryContextCleanupRegistrar<
3046 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3047
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003048 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003049 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003050 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003051 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 }
3053
Ahmed Charlesb8984322014-03-07 20:03:18 +00003054 std::unique_ptr<std::vector<const char *>> Args(
3055 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
3057 // Recover resources if we crash before exiting this method.
3058 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3059 ArgsCleanup(Args.get());
3060
3061 // Since the Clang C library is primarily used by batch tools dealing with
3062 // (often very broken) source code, where spell-checking can have a
3063 // significant negative impact on performance (particularly when
3064 // precompiled headers are involved), we disable it by default.
3065 // Only do this if we haven't found a spell-checking-related argument.
3066 bool FoundSpellCheckingArgument = false;
3067 for (int I = 0; I != num_command_line_args; ++I) {
3068 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3069 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3070 FoundSpellCheckingArgument = true;
3071 break;
3072 }
3073 }
3074 if (!FoundSpellCheckingArgument)
3075 Args->push_back("-fno-spell-checking");
3076
3077 Args->insert(Args->end(), command_line_args,
3078 command_line_args + num_command_line_args);
3079
3080 // The 'source_filename' argument is optional. If the caller does not
3081 // specify it then it is assumed that the source file is specified
3082 // in the actual argument list.
3083 // Put the source file after command_line_args otherwise if '-x' flag is
3084 // present it will be unused.
3085 if (source_filename)
3086 Args->push_back(source_filename);
3087
3088 // Do we need the detailed preprocessing record?
3089 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3090 Args->push_back("-Xclang");
3091 Args->push_back("-detailed-preprocessing-record");
3092 }
3093
3094 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003095 std::unique_ptr<ASTUnit> ErrUnit;
3096 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003097 Args->data(), Args->data() + Args->size(),
3098 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003099 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3100 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3101 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3102 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3103 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3104 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003106 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003107 if (!Unit && !ErrUnit)
3108 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003109
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 if (NumErrors != Diags->getClient()->getNumErrors()) {
3111 // Make sure to check that 'Unit' is non-NULL.
3112 if (CXXIdx->getDisplayDiagnostics())
3113 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3114 }
3115
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003116 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3117 return CXError_ASTReadError;
3118
3119 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3120 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003121}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003122
3123CXTranslationUnit
3124clang_parseTranslationUnit(CXIndex CIdx,
3125 const char *source_filename,
3126 const char *const *command_line_args,
3127 int num_command_line_args,
3128 struct CXUnsavedFile *unsaved_files,
3129 unsigned num_unsaved_files,
3130 unsigned options) {
3131 CXTranslationUnit TU;
3132 enum CXErrorCode Result = clang_parseTranslationUnit2(
3133 CIdx, source_filename, command_line_args, num_command_line_args,
3134 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003135 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003136 assert((TU && Result == CXError_Success) ||
3137 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003138 return TU;
3139}
3140
3141enum CXErrorCode clang_parseTranslationUnit2(
3142 CXIndex CIdx,
3143 const char *source_filename,
3144 const char *const *command_line_args,
3145 int num_command_line_args,
3146 struct CXUnsavedFile *unsaved_files,
3147 unsigned num_unsaved_files,
3148 unsigned options,
3149 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003150 LOG_FUNC_SECTION {
3151 *Log << source_filename << ": ";
3152 for (int i = 0; i != num_command_line_args; ++i)
3153 *Log << command_line_args[i] << " ";
3154 }
3155
Alp Toker9d85b182014-07-07 01:23:14 +00003156 if (num_unsaved_files && !unsaved_files)
3157 return CXError_InvalidArguments;
3158
Alp Toker5c532982014-07-07 22:42:03 +00003159 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003160 auto ParseTranslationUnitImpl = [=, &result] {
3161 result = clang_parseTranslationUnit_Impl(
3162 CIdx, source_filename, command_line_args, num_command_line_args,
3163 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3164 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 llvm::CrashRecoveryContext CRC;
3166
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003167 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3169 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3170 fprintf(stderr, " 'command_line_args' : [");
3171 for (int i = 0; i != num_command_line_args; ++i) {
3172 if (i)
3173 fprintf(stderr, ", ");
3174 fprintf(stderr, "'%s'", command_line_args[i]);
3175 }
3176 fprintf(stderr, "],\n");
3177 fprintf(stderr, " 'unsaved_files' : [");
3178 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3179 if (i)
3180 fprintf(stderr, ", ");
3181 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3182 unsaved_files[i].Length);
3183 }
3184 fprintf(stderr, "],\n");
3185 fprintf(stderr, " 'options' : %d,\n", options);
3186 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003187
3188 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003190 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003191 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 }
Alp Toker5c532982014-07-07 22:42:03 +00003193
3194 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003195}
3196
3197unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3198 return CXSaveTranslationUnit_None;
3199}
3200
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003201static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3202 const char *FileName,
3203 unsigned options) {
3204 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3206 setThreadBackgroundPriority();
3207
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003208 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3209 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003210}
3211
3212int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3213 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003214 LOG_FUNC_SECTION {
3215 *Log << TU << ' ' << FileName;
3216 }
3217
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003218 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003219 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003221 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003222
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003223 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3225 if (!CXXUnit->hasSema())
3226 return CXSaveError_InvalidTU;
3227
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003228 CXSaveError result;
3229 auto SaveTranslationUnitImpl = [=, &result]() {
3230 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3231 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003232
3233 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3234 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003235 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003236
3237 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3238 PrintLibclangResourceUsage(TU);
3239
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003240 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 }
3242
3243 // We have an AST that has invalid nodes due to compiler errors.
3244 // Use a crash recovery thread for protection.
3245
3246 llvm::CrashRecoveryContext CRC;
3247
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003248 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3250 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3251 fprintf(stderr, " 'options' : %d,\n", options);
3252 fprintf(stderr, "}\n");
3253
3254 return CXSaveError_Unknown;
3255
3256 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3257 PrintLibclangResourceUsage(TU);
3258 }
3259
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003260 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003261}
3262
3263void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3264 if (CTUnit) {
3265 // If the translation unit has been marked as unsafe to free, just discard
3266 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003267 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3268 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return;
3270
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003271 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003272 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3274 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003275 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 delete CTUnit;
3277 }
3278}
3279
3280unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3281 return CXReparse_None;
3282}
3283
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003284static CXErrorCode
3285clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3286 ArrayRef<CXUnsavedFile> unsaved_files,
3287 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003288 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003289 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003290 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003291 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003292 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
3294 // Reset the associated diagnostics.
3295 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003296 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003298 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3300 setThreadBackgroundPriority();
3301
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003302 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003304
3305 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3306 new std::vector<ASTUnit::RemappedFile>());
3307
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 // Recover resources if we crash before exiting this function.
3309 llvm::CrashRecoveryContextCleanupRegistrar<
3310 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003311
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003312 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003313 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003314 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003315 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003317
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003318 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3319 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003320 return CXError_Success;
3321 if (isASTReadError(CXXUnit))
3322 return CXError_ASTReadError;
3323 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003324}
3325
3326int clang_reparseTranslationUnit(CXTranslationUnit TU,
3327 unsigned num_unsaved_files,
3328 struct CXUnsavedFile *unsaved_files,
3329 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003330 LOG_FUNC_SECTION {
3331 *Log << TU;
3332 }
3333
Alp Toker9d85b182014-07-07 01:23:14 +00003334 if (num_unsaved_files && !unsaved_files)
3335 return CXError_InvalidArguments;
3336
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003337 CXErrorCode result;
3338 auto ReparseTranslationUnitImpl = [=, &result]() {
3339 result = clang_reparseTranslationUnit_Impl(
3340 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3341 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
3343 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003344 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003345 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 }
3347
3348 llvm::CrashRecoveryContext CRC;
3349
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003350 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003352 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003353 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3355 PrintLibclangResourceUsage(TU);
3356
Alp Toker5c532982014-07-07 22:42:03 +00003357 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358}
3359
3360
3361CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003362 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003363 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003364 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003365 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003366
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003367 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369}
3370
3371CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003372 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003373 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003374 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003375 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003376
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003377 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3379}
3380
3381} // end: extern "C"
3382
3383//===----------------------------------------------------------------------===//
3384// CXFile Operations.
3385//===----------------------------------------------------------------------===//
3386
3387extern "C" {
3388CXString clang_getFileName(CXFile SFile) {
3389 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003390 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003391
3392 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003393 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003394}
3395
3396time_t clang_getFileTime(CXFile SFile) {
3397 if (!SFile)
3398 return 0;
3399
3400 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3401 return FEnt->getModificationTime();
3402}
3403
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003404CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003405 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003406 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003407 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003408 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003409
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003410 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003411
3412 FileManager &FMgr = CXXUnit->getFileManager();
3413 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3414}
3415
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003416unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3417 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003418 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003419 LOG_BAD_TU(TU);
3420 return 0;
3421 }
3422
3423 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 return 0;
3425
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003426 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 FileEntry *FEnt = static_cast<FileEntry *>(file);
3428 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3429 .isFileMultipleIncludeGuarded(FEnt);
3430}
3431
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003432int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3433 if (!file || !outID)
3434 return 1;
3435
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003436 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003437 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3438 outID->data[0] = ID.getDevice();
3439 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003440 outID->data[2] = FEnt->getModificationTime();
3441 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003442}
3443
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003444int clang_File_isEqual(CXFile file1, CXFile file2) {
3445 if (file1 == file2)
3446 return true;
3447
3448 if (!file1 || !file2)
3449 return false;
3450
3451 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3452 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3453 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3454}
3455
Guy Benyei11169dd2012-12-18 14:30:41 +00003456} // end: extern "C"
3457
3458//===----------------------------------------------------------------------===//
3459// CXCursor Operations.
3460//===----------------------------------------------------------------------===//
3461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462static const Decl *getDeclFromExpr(const Stmt *E) {
3463 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 return getDeclFromExpr(CE->getSubExpr());
3465
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003466 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003468 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003472 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 if (PRE->isExplicitProperty())
3474 return PRE->getExplicitProperty();
3475 // It could be messaging both getter and setter as in:
3476 // ++myobj.myprop;
3477 // in which case prefer to associate the setter since it is less obvious
3478 // from inspecting the source that the setter is going to get called.
3479 if (PRE->isMessagingSetter())
3480 return PRE->getImplicitPropertySetter();
3481 return PRE->getImplicitPropertyGetter();
3482 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 if (Expr *Src = OVE->getSourceExpr())
3487 return getDeclFromExpr(Src);
3488
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 if (!CE->isElidable())
3493 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 return OME->getMethodDecl();
3496
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3501 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3504 isa<ParmVarDecl>(SizeOfPack->getPack()))
3505 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003506
3507 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003508}
3509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003510static SourceLocation getLocationFromExpr(const Expr *E) {
3511 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 return getLocationFromExpr(CE->getSubExpr());
3513
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003514 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003516 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003518 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003520 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003522 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003524 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 return PropRef->getLocation();
3526
3527 return E->getLocStart();
3528}
3529
3530extern "C" {
3531
3532unsigned clang_visitChildren(CXCursor parent,
3533 CXCursorVisitor visitor,
3534 CXClientData client_data) {
3535 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3536 /*VisitPreprocessorLast=*/false);
3537 return CursorVis.VisitChildren(parent);
3538}
3539
3540#ifndef __has_feature
3541#define __has_feature(x) 0
3542#endif
3543#if __has_feature(blocks)
3544typedef enum CXChildVisitResult
3545 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3546
3547static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3548 CXClientData client_data) {
3549 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3550 return block(cursor, parent);
3551}
3552#else
3553// If we are compiled with a compiler that doesn't have native blocks support,
3554// define and call the block manually, so the
3555typedef struct _CXChildVisitResult
3556{
3557 void *isa;
3558 int flags;
3559 int reserved;
3560 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3561 CXCursor);
3562} *CXCursorVisitorBlock;
3563
3564static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3565 CXClientData client_data) {
3566 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3567 return block->invoke(block, cursor, parent);
3568}
3569#endif
3570
3571
3572unsigned clang_visitChildrenWithBlock(CXCursor parent,
3573 CXCursorVisitorBlock block) {
3574 return clang_visitChildren(parent, visitWithBlock, block);
3575}
3576
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003577static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003579 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003581 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003583 if (const ObjCPropertyImplDecl *PropImpl =
3584 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003586 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003588 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003590 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003591
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003592 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 }
3594
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003595 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3600 // and returns different names. NamedDecl returns the class name and
3601 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003603
3604 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003605 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
3607 SmallString<1024> S;
3608 llvm::raw_svector_ostream os(S);
3609 ND->printName(os);
3610
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003611 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003612}
3613
3614CXString clang_getCursorSpelling(CXCursor C) {
3615 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003616 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003617
3618 if (clang_isReference(C.kind)) {
3619 switch (C.kind) {
3620 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003621 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003625 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 }
3628 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003629 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 }
3633 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003634 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 }
3637 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003638 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 assert(Type && "Missing type decl");
3640
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003641 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 getAsString());
3643 }
3644 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003645 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 assert(Template && "Missing template decl");
3647
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003648 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 }
3650
3651 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003652 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 assert(NS && "Missing namespace decl");
3654
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003655 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 }
3657
3658 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003659 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 assert(Field && "Missing member decl");
3661
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003662 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 }
3664
3665 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003666 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 assert(Label && "Missing label");
3668
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 }
3671
3672 case CXCursor_OverloadedDeclRef: {
3673 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3675 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003676 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003677 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003680 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 OverloadedTemplateStorage *Ovl
3682 = Storage.get<OverloadedTemplateStorage*>();
3683 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003684 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 }
3687
3688 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003689 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 assert(Var && "Missing variable decl");
3691
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003692 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 }
3694
3695 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 }
3698 }
3699
3700 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003701 const Expr *E = getCursorExpr(C);
3702
3703 if (C.kind == CXCursor_ObjCStringLiteral ||
3704 C.kind == CXCursor_StringLiteral) {
3705 const StringLiteral *SLit;
3706 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3707 SLit = OSL->getString();
3708 } else {
3709 SLit = cast<StringLiteral>(E);
3710 }
3711 SmallString<256> Buf;
3712 llvm::raw_svector_ostream OS(Buf);
3713 SLit->outputString(OS);
3714 return cxstring::createDup(OS.str());
3715 }
3716
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003717 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 if (D)
3719 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003720 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722
3723 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003724 const Stmt *S = getCursorStmt(C);
3725 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003727
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003728 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 }
3730
3731 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 ->getNameStart());
3734
3735 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 ->getNameStart());
3738
3739 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003740 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741
3742 if (clang_isDeclaration(C.kind))
3743 return getDeclSpelling(getCursorDecl(C));
3744
3745 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003746 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003747 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 }
3749
3750 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003751 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003752 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 }
3754
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003755 if (C.kind == CXCursor_PackedAttr) {
3756 return cxstring::createRef("packed");
3757 }
3758
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003759 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003760}
3761
3762CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3763 unsigned pieceIndex,
3764 unsigned options) {
3765 if (clang_Cursor_isNull(C))
3766 return clang_getNullRange();
3767
3768 ASTContext &Ctx = getCursorContext(C);
3769
3770 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003771 const Stmt *S = getCursorStmt(C);
3772 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 if (pieceIndex > 0)
3774 return clang_getNullRange();
3775 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3776 }
3777
3778 return clang_getNullRange();
3779 }
3780
3781 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003782 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3784 if (pieceIndex >= ME->getNumSelectorLocs())
3785 return clang_getNullRange();
3786 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3787 }
3788 }
3789
3790 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3791 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003792 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3794 if (pieceIndex >= MD->getNumSelectorLocs())
3795 return clang_getNullRange();
3796 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3797 }
3798 }
3799
3800 if (C.kind == CXCursor_ObjCCategoryDecl ||
3801 C.kind == CXCursor_ObjCCategoryImplDecl) {
3802 if (pieceIndex > 0)
3803 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003804 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3806 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003807 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3809 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3810 }
3811
3812 if (C.kind == CXCursor_ModuleImportDecl) {
3813 if (pieceIndex > 0)
3814 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003815 if (const ImportDecl *ImportD =
3816 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3818 if (!Locs.empty())
3819 return cxloc::translateSourceRange(Ctx,
3820 SourceRange(Locs.front(), Locs.back()));
3821 }
3822 return clang_getNullRange();
3823 }
3824
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003825 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3826 C.kind == CXCursor_ConversionFunction) {
3827 if (pieceIndex > 0)
3828 return clang_getNullRange();
3829 if (const FunctionDecl *FD =
3830 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3831 DeclarationNameInfo FunctionName = FD->getNameInfo();
3832 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3833 }
3834 return clang_getNullRange();
3835 }
3836
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 // FIXME: A CXCursor_InclusionDirective should give the location of the
3838 // filename, but we don't keep track of this.
3839
3840 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3841 // but we don't keep track of this.
3842
3843 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3844 // but we don't keep track of this.
3845
3846 // Default handling, give the location of the cursor.
3847
3848 if (pieceIndex > 0)
3849 return clang_getNullRange();
3850
3851 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3852 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3853 return cxloc::translateSourceRange(Ctx, Loc);
3854}
3855
Eli Bendersky44a206f2014-07-31 18:04:56 +00003856CXString clang_Cursor_getMangling(CXCursor C) {
3857 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3858 return cxstring::createEmpty();
3859
Eli Bendersky44a206f2014-07-31 18:04:56 +00003860 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003861 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003862 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3863 return cxstring::createEmpty();
3864
Eli Bendersky79759592014-08-01 15:01:10 +00003865 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003866 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003867 ASTContext &Ctx = ND->getASTContext();
3868 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003869
Eli Bendersky79759592014-08-01 15:01:10 +00003870 std::string FrontendBuf;
3871 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3872 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003873
Eli Bendersky79759592014-08-01 15:01:10 +00003874 // Now apply backend mangling.
3875 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003876 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003877
3878 std::string FinalBuf;
3879 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003880 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3881 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003882
3883 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003884}
3885
Guy Benyei11169dd2012-12-18 14:30:41 +00003886CXString clang_getCursorDisplayName(CXCursor C) {
3887 if (!clang_isDeclaration(C.kind))
3888 return clang_getCursorSpelling(C);
3889
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003892 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003893
3894 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003895 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 D = FunTmpl->getTemplatedDecl();
3897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003898 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 SmallString<64> Str;
3900 llvm::raw_svector_ostream OS(Str);
3901 OS << *Function;
3902 if (Function->getPrimaryTemplate())
3903 OS << "<>";
3904 OS << "(";
3905 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3906 if (I)
3907 OS << ", ";
3908 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3909 }
3910
3911 if (Function->isVariadic()) {
3912 if (Function->getNumParams())
3913 OS << ", ";
3914 OS << "...";
3915 }
3916 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003917 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 }
3919
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 SmallString<64> Str;
3922 llvm::raw_svector_ostream OS(Str);
3923 OS << *ClassTemplate;
3924 OS << "<";
3925 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3926 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3927 if (I)
3928 OS << ", ";
3929
3930 NamedDecl *Param = Params->getParam(I);
3931 if (Param->getIdentifier()) {
3932 OS << Param->getIdentifier()->getName();
3933 continue;
3934 }
3935
3936 // There is no parameter name, which makes this tricky. Try to come up
3937 // with something useful that isn't too long.
3938 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3939 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3940 else if (NonTypeTemplateParmDecl *NTTP
3941 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3942 OS << NTTP->getType().getAsString(Policy);
3943 else
3944 OS << "template<...> class";
3945 }
3946
3947 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003948 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 }
3950
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003951 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3953 // If the type was explicitly written, use that.
3954 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003955 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003956
Benjamin Kramer9170e912013-02-22 15:46:01 +00003957 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 llvm::raw_svector_ostream OS(Str);
3959 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003960 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 ClassSpec->getTemplateArgs().data(),
3962 ClassSpec->getTemplateArgs().size(),
3963 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003964 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 }
3966
3967 return clang_getCursorSpelling(C);
3968}
3969
3970CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3971 switch (Kind) {
3972 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004050 case CXCursor_OMPArraySectionExpr:
4051 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004102 case CXCursor_ObjCSelfExpr:
4103 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004192 case CXCursor_SEHLeaveStmt:
4193 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004222 case CXCursor_PackedAttr:
4223 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004224 case CXCursor_PureAttr:
4225 return cxstring::createRef("attribute(pure)");
4226 case CXCursor_ConstAttr:
4227 return cxstring::createRef("attribute(const)");
4228 case CXCursor_NoDuplicateAttr:
4229 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004230 case CXCursor_CUDAConstantAttr:
4231 return cxstring::createRef("attribute(constant)");
4232 case CXCursor_CUDADeviceAttr:
4233 return cxstring::createRef("attribute(device)");
4234 case CXCursor_CUDAGlobalAttr:
4235 return cxstring::createRef("attribute(global)");
4236 case CXCursor_CUDAHostAttr:
4237 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004238 case CXCursor_CUDASharedAttr:
4239 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004288 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004289 return cxstring::createRef("OMPParallelDirective");
4290 case CXCursor_OMPSimdDirective:
4291 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004292 case CXCursor_OMPForDirective:
4293 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004294 case CXCursor_OMPForSimdDirective:
4295 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004296 case CXCursor_OMPSectionsDirective:
4297 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004298 case CXCursor_OMPSectionDirective:
4299 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004300 case CXCursor_OMPSingleDirective:
4301 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004302 case CXCursor_OMPMasterDirective:
4303 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004304 case CXCursor_OMPCriticalDirective:
4305 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004306 case CXCursor_OMPParallelForDirective:
4307 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004308 case CXCursor_OMPParallelForSimdDirective:
4309 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004310 case CXCursor_OMPParallelSectionsDirective:
4311 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004312 case CXCursor_OMPTaskDirective:
4313 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004314 case CXCursor_OMPTaskyieldDirective:
4315 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004316 case CXCursor_OMPBarrierDirective:
4317 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004318 case CXCursor_OMPTaskwaitDirective:
4319 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004320 case CXCursor_OMPTaskgroupDirective:
4321 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004322 case CXCursor_OMPFlushDirective:
4323 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004324 case CXCursor_OMPOrderedDirective:
4325 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004326 case CXCursor_OMPAtomicDirective:
4327 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004328 case CXCursor_OMPTargetDirective:
4329 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004330 case CXCursor_OMPTargetDataDirective:
4331 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004332 case CXCursor_OMPTeamsDirective:
4333 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004334 case CXCursor_OMPCancellationPointDirective:
4335 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004336 case CXCursor_OMPCancelDirective:
4337 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004338 case CXCursor_OverloadCandidate:
4339 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 }
4341
4342 llvm_unreachable("Unhandled CXCursorKind");
4343}
4344
4345struct GetCursorData {
4346 SourceLocation TokenBeginLoc;
4347 bool PointsAtMacroArgExpansion;
4348 bool VisitedObjCPropertyImplDecl;
4349 SourceLocation VisitedDeclaratorDeclStartLoc;
4350 CXCursor &BestCursor;
4351
4352 GetCursorData(SourceManager &SM,
4353 SourceLocation tokenBegin, CXCursor &outputCursor)
4354 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4355 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4356 VisitedObjCPropertyImplDecl = false;
4357 }
4358};
4359
4360static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4361 CXCursor parent,
4362 CXClientData client_data) {
4363 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4364 CXCursor *BestCursor = &Data->BestCursor;
4365
4366 // If we point inside a macro argument we should provide info of what the
4367 // token is so use the actual cursor, don't replace it with a macro expansion
4368 // cursor.
4369 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4370 return CXChildVisit_Recurse;
4371
4372 if (clang_isDeclaration(cursor.kind)) {
4373 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004374 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4376 if (MD->isImplicit())
4377 return CXChildVisit_Break;
4378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004379 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4381 // Check that when we have multiple @class references in the same line,
4382 // that later ones do not override the previous ones.
4383 // If we have:
4384 // @class Foo, Bar;
4385 // source ranges for both start at '@', so 'Bar' will end up overriding
4386 // 'Foo' even though the cursor location was at 'Foo'.
4387 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4388 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004389 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4391 if (PrevID != ID &&
4392 !PrevID->isThisDeclarationADefinition() &&
4393 !ID->isThisDeclarationADefinition())
4394 return CXChildVisit_Break;
4395 }
4396
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4399 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4400 // Check that when we have multiple declarators in the same line,
4401 // that later ones do not override the previous ones.
4402 // If we have:
4403 // int Foo, Bar;
4404 // source ranges for both start at 'int', so 'Bar' will end up overriding
4405 // 'Foo' even though the cursor location was at 'Foo'.
4406 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4407 return CXChildVisit_Break;
4408 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004410 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4412 (void)PropImp;
4413 // Check that when we have multiple @synthesize in the same line,
4414 // that later ones do not override the previous ones.
4415 // If we have:
4416 // @synthesize Foo, Bar;
4417 // source ranges for both start at '@', so 'Bar' will end up overriding
4418 // 'Foo' even though the cursor location was at 'Foo'.
4419 if (Data->VisitedObjCPropertyImplDecl)
4420 return CXChildVisit_Break;
4421 Data->VisitedObjCPropertyImplDecl = true;
4422 }
4423 }
4424
4425 if (clang_isExpression(cursor.kind) &&
4426 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004427 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 // Avoid having the cursor of an expression replace the declaration cursor
4429 // when the expression source range overlaps the declaration range.
4430 // This can happen for C++ constructor expressions whose range generally
4431 // include the variable declaration, e.g.:
4432 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4433 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4434 D->getLocation() == Data->TokenBeginLoc)
4435 return CXChildVisit_Break;
4436 }
4437 }
4438
4439 // If our current best cursor is the construction of a temporary object,
4440 // don't replace that cursor with a type reference, because we want
4441 // clang_getCursor() to point at the constructor.
4442 if (clang_isExpression(BestCursor->kind) &&
4443 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4444 cursor.kind == CXCursor_TypeRef) {
4445 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4446 // as having the actual point on the type reference.
4447 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4448 return CXChildVisit_Recurse;
4449 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004450
4451 // If we already have an Objective-C superclass reference, don't
4452 // update it further.
4453 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4454 return CXChildVisit_Break;
4455
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 *BestCursor = cursor;
4457 return CXChildVisit_Recurse;
4458}
4459
4460CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004461 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004462 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004464 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004465
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004466 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4468
4469 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4470 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4471
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004472 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 CXFile SearchFile;
4474 unsigned SearchLine, SearchColumn;
4475 CXFile ResultFile;
4476 unsigned ResultLine, ResultColumn;
4477 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4478 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4479 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004480
4481 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4482 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004483 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004484 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 SearchFileName = clang_getFileName(SearchFile);
4486 ResultFileName = clang_getFileName(ResultFile);
4487 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4488 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004489 *Log << llvm::format("(%s:%d:%d) = %s",
4490 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4491 clang_getCString(KindSpelling))
4492 << llvm::format("(%s:%d:%d):%s%s",
4493 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4494 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 clang_disposeString(SearchFileName);
4496 clang_disposeString(ResultFileName);
4497 clang_disposeString(KindSpelling);
4498 clang_disposeString(USR);
4499
4500 CXCursor Definition = clang_getCursorDefinition(Result);
4501 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4502 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4503 CXString DefinitionKindSpelling
4504 = clang_getCursorKindSpelling(Definition.kind);
4505 CXFile DefinitionFile;
4506 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004507 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004508 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004510 *Log << llvm::format(" -> %s(%s:%d:%d)",
4511 clang_getCString(DefinitionKindSpelling),
4512 clang_getCString(DefinitionFileName),
4513 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 clang_disposeString(DefinitionFileName);
4515 clang_disposeString(DefinitionKindSpelling);
4516 }
4517 }
4518
4519 return Result;
4520}
4521
4522CXCursor clang_getNullCursor(void) {
4523 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4524}
4525
4526unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004527 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4528 // can't set consistently. For example, when visiting a DeclStmt we will set
4529 // it but we don't set it on the result of clang_getCursorDefinition for
4530 // a reference of the same declaration.
4531 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4532 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4533 // to provide that kind of info.
4534 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004535 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004536 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004537 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004538
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 return X == Y;
4540}
4541
4542unsigned clang_hashCursor(CXCursor C) {
4543 unsigned Index = 0;
4544 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4545 Index = 1;
4546
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 std::make_pair(C.kind, C.data[Index]));
4549}
4550
4551unsigned clang_isInvalid(enum CXCursorKind K) {
4552 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4553}
4554
4555unsigned clang_isDeclaration(enum CXCursorKind K) {
4556 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4557 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4558}
4559
4560unsigned clang_isReference(enum CXCursorKind K) {
4561 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4562}
4563
4564unsigned clang_isExpression(enum CXCursorKind K) {
4565 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4566}
4567
4568unsigned clang_isStatement(enum CXCursorKind K) {
4569 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4570}
4571
4572unsigned clang_isAttribute(enum CXCursorKind K) {
4573 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4574}
4575
4576unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4577 return K == CXCursor_TranslationUnit;
4578}
4579
4580unsigned clang_isPreprocessing(enum CXCursorKind K) {
4581 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4582}
4583
4584unsigned clang_isUnexposed(enum CXCursorKind K) {
4585 switch (K) {
4586 case CXCursor_UnexposedDecl:
4587 case CXCursor_UnexposedExpr:
4588 case CXCursor_UnexposedStmt:
4589 case CXCursor_UnexposedAttr:
4590 return true;
4591 default:
4592 return false;
4593 }
4594}
4595
4596CXCursorKind clang_getCursorKind(CXCursor C) {
4597 return C.kind;
4598}
4599
4600CXSourceLocation clang_getCursorLocation(CXCursor C) {
4601 if (clang_isReference(C.kind)) {
4602 switch (C.kind) {
4603 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004604 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 = getCursorObjCSuperClassRef(C);
4606 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4607 }
4608
4609 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004610 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 = getCursorObjCProtocolRef(C);
4612 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4613 }
4614
4615 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004616 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 = getCursorObjCClassRef(C);
4618 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4619 }
4620
4621 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004622 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4624 }
4625
4626 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 std::pair<const TemplateDecl *, SourceLocation> P =
4628 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4630 }
4631
4632 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4635 }
4636
4637 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004638 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4640 }
4641
4642 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004643 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4645 }
4646
4647 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004648 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 if (!BaseSpec)
4650 return clang_getNullLocation();
4651
4652 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4653 return cxloc::translateSourceLocation(getCursorContext(C),
4654 TSInfo->getTypeLoc().getBeginLoc());
4655
4656 return cxloc::translateSourceLocation(getCursorContext(C),
4657 BaseSpec->getLocStart());
4658 }
4659
4660 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004661 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4663 }
4664
4665 case CXCursor_OverloadedDeclRef:
4666 return cxloc::translateSourceLocation(getCursorContext(C),
4667 getCursorOverloadedDeclRef(C).second);
4668
4669 default:
4670 // FIXME: Need a way to enumerate all non-reference cases.
4671 llvm_unreachable("Missed a reference kind");
4672 }
4673 }
4674
4675 if (clang_isExpression(C.kind))
4676 return cxloc::translateSourceLocation(getCursorContext(C),
4677 getLocationFromExpr(getCursorExpr(C)));
4678
4679 if (clang_isStatement(C.kind))
4680 return cxloc::translateSourceLocation(getCursorContext(C),
4681 getCursorStmt(C)->getLocStart());
4682
4683 if (C.kind == CXCursor_PreprocessingDirective) {
4684 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4685 return cxloc::translateSourceLocation(getCursorContext(C), L);
4686 }
4687
4688 if (C.kind == CXCursor_MacroExpansion) {
4689 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004690 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return cxloc::translateSourceLocation(getCursorContext(C), L);
4692 }
4693
4694 if (C.kind == CXCursor_MacroDefinition) {
4695 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4696 return cxloc::translateSourceLocation(getCursorContext(C), L);
4697 }
4698
4699 if (C.kind == CXCursor_InclusionDirective) {
4700 SourceLocation L
4701 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4702 return cxloc::translateSourceLocation(getCursorContext(C), L);
4703 }
4704
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004705 if (clang_isAttribute(C.kind)) {
4706 SourceLocation L
4707 = cxcursor::getCursorAttr(C)->getLocation();
4708 return cxloc::translateSourceLocation(getCursorContext(C), L);
4709 }
4710
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 if (!clang_isDeclaration(C.kind))
4712 return clang_getNullLocation();
4713
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004714 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 if (!D)
4716 return clang_getNullLocation();
4717
4718 SourceLocation Loc = D->getLocation();
4719 // FIXME: Multiple variables declared in a single declaration
4720 // currently lack the information needed to correctly determine their
4721 // ranges when accounting for the type-specifier. We use context
4722 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4723 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 if (!cxcursor::isFirstInDeclGroup(C))
4726 Loc = VD->getLocation();
4727 }
4728
4729 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 Loc = MD->getSelectorStartLoc();
4732
4733 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4734}
4735
4736} // end extern "C"
4737
4738CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4739 assert(TU);
4740
4741 // Guard against an invalid SourceLocation, or we may assert in one
4742 // of the following calls.
4743 if (SLoc.isInvalid())
4744 return clang_getNullCursor();
4745
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004746 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747
4748 // Translate the given source location to make it point at the beginning of
4749 // the token under the cursor.
4750 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4751 CXXUnit->getASTContext().getLangOpts());
4752
4753 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4754 if (SLoc.isValid()) {
4755 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4756 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4757 /*VisitPreprocessorLast=*/true,
4758 /*VisitIncludedEntities=*/false,
4759 SourceLocation(SLoc));
4760 CursorVis.visitFileRegion();
4761 }
4762
4763 return Result;
4764}
4765
4766static SourceRange getRawCursorExtent(CXCursor C) {
4767 if (clang_isReference(C.kind)) {
4768 switch (C.kind) {
4769 case CXCursor_ObjCSuperClassRef:
4770 return getCursorObjCSuperClassRef(C).second;
4771
4772 case CXCursor_ObjCProtocolRef:
4773 return getCursorObjCProtocolRef(C).second;
4774
4775 case CXCursor_ObjCClassRef:
4776 return getCursorObjCClassRef(C).second;
4777
4778 case CXCursor_TypeRef:
4779 return getCursorTypeRef(C).second;
4780
4781 case CXCursor_TemplateRef:
4782 return getCursorTemplateRef(C).second;
4783
4784 case CXCursor_NamespaceRef:
4785 return getCursorNamespaceRef(C).second;
4786
4787 case CXCursor_MemberRef:
4788 return getCursorMemberRef(C).second;
4789
4790 case CXCursor_CXXBaseSpecifier:
4791 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4792
4793 case CXCursor_LabelRef:
4794 return getCursorLabelRef(C).second;
4795
4796 case CXCursor_OverloadedDeclRef:
4797 return getCursorOverloadedDeclRef(C).second;
4798
4799 case CXCursor_VariableRef:
4800 return getCursorVariableRef(C).second;
4801
4802 default:
4803 // FIXME: Need a way to enumerate all non-reference cases.
4804 llvm_unreachable("Missed a reference kind");
4805 }
4806 }
4807
4808 if (clang_isExpression(C.kind))
4809 return getCursorExpr(C)->getSourceRange();
4810
4811 if (clang_isStatement(C.kind))
4812 return getCursorStmt(C)->getSourceRange();
4813
4814 if (clang_isAttribute(C.kind))
4815 return getCursorAttr(C)->getRange();
4816
4817 if (C.kind == CXCursor_PreprocessingDirective)
4818 return cxcursor::getCursorPreprocessingDirective(C);
4819
4820 if (C.kind == CXCursor_MacroExpansion) {
4821 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004822 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 return TU->mapRangeFromPreamble(Range);
4824 }
4825
4826 if (C.kind == CXCursor_MacroDefinition) {
4827 ASTUnit *TU = getCursorASTUnit(C);
4828 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4829 return TU->mapRangeFromPreamble(Range);
4830 }
4831
4832 if (C.kind == CXCursor_InclusionDirective) {
4833 ASTUnit *TU = getCursorASTUnit(C);
4834 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4835 return TU->mapRangeFromPreamble(Range);
4836 }
4837
4838 if (C.kind == CXCursor_TranslationUnit) {
4839 ASTUnit *TU = getCursorASTUnit(C);
4840 FileID MainID = TU->getSourceManager().getMainFileID();
4841 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4842 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4843 return SourceRange(Start, End);
4844 }
4845
4846 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004847 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 if (!D)
4849 return SourceRange();
4850
4851 SourceRange R = D->getSourceRange();
4852 // FIXME: Multiple variables declared in a single declaration
4853 // currently lack the information needed to correctly determine their
4854 // ranges when accounting for the type-specifier. We use context
4855 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4856 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 if (!cxcursor::isFirstInDeclGroup(C))
4859 R.setBegin(VD->getLocation());
4860 }
4861 return R;
4862 }
4863 return SourceRange();
4864}
4865
4866/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4867/// the decl-specifier-seq for declarations.
4868static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
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
4876 // Adjust the start of the location for declarations preceded by
4877 // declaration specifiers.
4878 SourceLocation StartLoc;
4879 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4880 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4881 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4884 StartLoc = TI->getTypeLoc().getLocStart();
4885 }
4886
4887 if (StartLoc.isValid() && R.getBegin().isValid() &&
4888 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4889 R.setBegin(StartLoc);
4890
4891 // FIXME: Multiple variables declared in a single declaration
4892 // currently lack the information needed to correctly determine their
4893 // ranges when accounting for the type-specifier. We use context
4894 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4895 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 if (!cxcursor::isFirstInDeclGroup(C))
4898 R.setBegin(VD->getLocation());
4899 }
4900
4901 return R;
4902 }
4903
4904 return getRawCursorExtent(C);
4905}
4906
4907extern "C" {
4908
4909CXSourceRange clang_getCursorExtent(CXCursor C) {
4910 SourceRange R = getRawCursorExtent(C);
4911 if (R.isInvalid())
4912 return clang_getNullRange();
4913
4914 return cxloc::translateSourceRange(getCursorContext(C), R);
4915}
4916
4917CXCursor clang_getCursorReferenced(CXCursor C) {
4918 if (clang_isInvalid(C.kind))
4919 return clang_getNullCursor();
4920
4921 CXTranslationUnit tu = getCursorTU(C);
4922 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004923 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 if (!D)
4925 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004928 if (const ObjCPropertyImplDecl *PropImpl =
4929 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4931 return MakeCXCursor(Property, tu);
4932
4933 return C;
4934 }
4935
4936 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 const Expr *E = getCursorExpr(C);
4938 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004939 if (D) {
4940 CXCursor declCursor = MakeCXCursor(D, tu);
4941 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4942 declCursor);
4943 return declCursor;
4944 }
4945
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 return MakeCursorOverloadedDeclRef(Ovl, tu);
4948
4949 return clang_getNullCursor();
4950 }
4951
4952 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004953 const Stmt *S = getCursorStmt(C);
4954 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (LabelDecl *label = Goto->getLabel())
4956 if (LabelStmt *labelS = label->getStmt())
4957 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4958
4959 return clang_getNullCursor();
4960 }
Richard Smith66a81862015-05-04 02:25:31 +00004961
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004963 if (const MacroDefinitionRecord *Def =
4964 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004965 return MakeMacroDefinitionCursor(Def, tu);
4966 }
4967
4968 if (!clang_isReference(C.kind))
4969 return clang_getNullCursor();
4970
4971 switch (C.kind) {
4972 case CXCursor_ObjCSuperClassRef:
4973 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4974
4975 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004976 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4977 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 return MakeCXCursor(Def, tu);
4979
4980 return MakeCXCursor(Prot, tu);
4981 }
4982
4983 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004984 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4985 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 return MakeCXCursor(Def, tu);
4987
4988 return MakeCXCursor(Class, tu);
4989 }
4990
4991 case CXCursor_TypeRef:
4992 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4993
4994 case CXCursor_TemplateRef:
4995 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4996
4997 case CXCursor_NamespaceRef:
4998 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4999
5000 case CXCursor_MemberRef:
5001 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5002
5003 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005004 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5006 tu ));
5007 }
5008
5009 case CXCursor_LabelRef:
5010 // FIXME: We end up faking the "parent" declaration here because we
5011 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005012 return MakeCXCursor(getCursorLabelRef(C).first,
5013 cxtu::getASTUnit(tu)->getASTContext()
5014 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 tu);
5016
5017 case CXCursor_OverloadedDeclRef:
5018 return C;
5019
5020 case CXCursor_VariableRef:
5021 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5022
5023 default:
5024 // We would prefer to enumerate all non-reference cursor kinds here.
5025 llvm_unreachable("Unhandled reference cursor kind");
5026 }
5027}
5028
5029CXCursor clang_getCursorDefinition(CXCursor C) {
5030 if (clang_isInvalid(C.kind))
5031 return clang_getNullCursor();
5032
5033 CXTranslationUnit TU = getCursorTU(C);
5034
5035 bool WasReference = false;
5036 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5037 C = clang_getCursorReferenced(C);
5038 WasReference = true;
5039 }
5040
5041 if (C.kind == CXCursor_MacroExpansion)
5042 return clang_getCursorReferenced(C);
5043
5044 if (!clang_isDeclaration(C.kind))
5045 return clang_getNullCursor();
5046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005047 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 if (!D)
5049 return clang_getNullCursor();
5050
5051 switch (D->getKind()) {
5052 // Declaration kinds that don't really separate the notions of
5053 // declaration and definition.
5054 case Decl::Namespace:
5055 case Decl::Typedef:
5056 case Decl::TypeAlias:
5057 case Decl::TypeAliasTemplate:
5058 case Decl::TemplateTypeParm:
5059 case Decl::EnumConstant:
5060 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005061 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 case Decl::IndirectField:
5063 case Decl::ObjCIvar:
5064 case Decl::ObjCAtDefsField:
5065 case Decl::ImplicitParam:
5066 case Decl::ParmVar:
5067 case Decl::NonTypeTemplateParm:
5068 case Decl::TemplateTemplateParm:
5069 case Decl::ObjCCategoryImpl:
5070 case Decl::ObjCImplementation:
5071 case Decl::AccessSpec:
5072 case Decl::LinkageSpec:
5073 case Decl::ObjCPropertyImpl:
5074 case Decl::FileScopeAsm:
5075 case Decl::StaticAssert:
5076 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005077 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 case Decl::Label: // FIXME: Is this right??
5079 case Decl::ClassScopeFunctionSpecialization:
5080 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005081 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005082 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 return C;
5084
5085 // Declaration kinds that don't make any sense here, but are
5086 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005087 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005089 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 break;
5091
5092 // Declaration kinds for which the definition is not resolvable.
5093 case Decl::UnresolvedUsingTypename:
5094 case Decl::UnresolvedUsingValue:
5095 break;
5096
5097 case Decl::UsingDirective:
5098 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5099 TU);
5100
5101 case Decl::NamespaceAlias:
5102 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5103
5104 case Decl::Enum:
5105 case Decl::Record:
5106 case Decl::CXXRecord:
5107 case Decl::ClassTemplateSpecialization:
5108 case Decl::ClassTemplatePartialSpecialization:
5109 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5110 return MakeCXCursor(Def, TU);
5111 return clang_getNullCursor();
5112
5113 case Decl::Function:
5114 case Decl::CXXMethod:
5115 case Decl::CXXConstructor:
5116 case Decl::CXXDestructor:
5117 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005118 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005120 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 return clang_getNullCursor();
5122 }
5123
Larisse Voufo39a1e502013-08-06 01:03:05 +00005124 case Decl::Var:
5125 case Decl::VarTemplateSpecialization:
5126 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005128 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 return MakeCXCursor(Def, TU);
5130 return clang_getNullCursor();
5131 }
5132
5133 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005134 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5136 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5137 return clang_getNullCursor();
5138 }
5139
5140 case Decl::ClassTemplate: {
5141 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5142 ->getDefinition())
5143 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5144 TU);
5145 return clang_getNullCursor();
5146 }
5147
Larisse Voufo39a1e502013-08-06 01:03:05 +00005148 case Decl::VarTemplate: {
5149 if (VarDecl *Def =
5150 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5151 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5152 return clang_getNullCursor();
5153 }
5154
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 case Decl::Using:
5156 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5157 D->getLocation(), TU);
5158
5159 case Decl::UsingShadow:
5160 return clang_getCursorDefinition(
5161 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5162 TU));
5163
5164 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005165 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 if (Method->isThisDeclarationADefinition())
5167 return C;
5168
5169 // Dig out the method definition in the associated
5170 // @implementation, if we have it.
5171 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005172 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5174 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5175 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5176 Method->isInstanceMethod()))
5177 if (Def->isThisDeclarationADefinition())
5178 return MakeCXCursor(Def, TU);
5179
5180 return clang_getNullCursor();
5181 }
5182
5183 case Decl::ObjCCategory:
5184 if (ObjCCategoryImplDecl *Impl
5185 = cast<ObjCCategoryDecl>(D)->getImplementation())
5186 return MakeCXCursor(Impl, TU);
5187 return clang_getNullCursor();
5188
5189 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005190 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 return MakeCXCursor(Def, TU);
5192 return clang_getNullCursor();
5193
5194 case Decl::ObjCInterface: {
5195 // There are two notions of a "definition" for an Objective-C
5196 // class: the interface and its implementation. When we resolved a
5197 // reference to an Objective-C class, produce the @interface as
5198 // the definition; when we were provided with the interface,
5199 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005200 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005202 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 return MakeCXCursor(Def, TU);
5204 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5205 return MakeCXCursor(Impl, TU);
5206 return clang_getNullCursor();
5207 }
5208
5209 case Decl::ObjCProperty:
5210 // FIXME: We don't really know where to find the
5211 // ObjCPropertyImplDecls that implement this property.
5212 return clang_getNullCursor();
5213
5214 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005215 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005217 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 return MakeCXCursor(Def, TU);
5219
5220 return clang_getNullCursor();
5221
5222 case Decl::Friend:
5223 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5224 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5225 return clang_getNullCursor();
5226
5227 case Decl::FriendTemplate:
5228 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5229 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5230 return clang_getNullCursor();
5231 }
5232
5233 return clang_getNullCursor();
5234}
5235
5236unsigned clang_isCursorDefinition(CXCursor C) {
5237 if (!clang_isDeclaration(C.kind))
5238 return 0;
5239
5240 return clang_getCursorDefinition(C) == C;
5241}
5242
5243CXCursor clang_getCanonicalCursor(CXCursor C) {
5244 if (!clang_isDeclaration(C.kind))
5245 return C;
5246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005247 if (const Decl *D = getCursorDecl(C)) {
5248 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5250 return MakeCXCursor(CatD, getCursorTU(C));
5251
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005252 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5253 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 return MakeCXCursor(IFD, getCursorTU(C));
5255
5256 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5257 }
5258
5259 return C;
5260}
5261
5262int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5263 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5264}
5265
5266unsigned clang_getNumOverloadedDecls(CXCursor C) {
5267 if (C.kind != CXCursor_OverloadedDeclRef)
5268 return 0;
5269
5270 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005271 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 return E->getNumDecls();
5273
5274 if (OverloadedTemplateStorage *S
5275 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5276 return S->size();
5277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005278 const Decl *D = Storage.get<const Decl *>();
5279 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 return Using->shadow_size();
5281
5282 return 0;
5283}
5284
5285CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5286 if (cursor.kind != CXCursor_OverloadedDeclRef)
5287 return clang_getNullCursor();
5288
5289 if (index >= clang_getNumOverloadedDecls(cursor))
5290 return clang_getNullCursor();
5291
5292 CXTranslationUnit TU = getCursorTU(cursor);
5293 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).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 MakeCXCursor(E->decls_begin()[index], TU);
5296
5297 if (OverloadedTemplateStorage *S
5298 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5299 return MakeCXCursor(S->begin()[index], TU);
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 // FIXME: This is, unfortunately, linear time.
5304 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5305 std::advance(Pos, index);
5306 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5307 }
5308
5309 return clang_getNullCursor();
5310}
5311
5312void clang_getDefinitionSpellingAndExtent(CXCursor C,
5313 const char **startBuf,
5314 const char **endBuf,
5315 unsigned *startLine,
5316 unsigned *startColumn,
5317 unsigned *endLine,
5318 unsigned *endColumn) {
5319 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005320 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5322
5323 SourceManager &SM = FD->getASTContext().getSourceManager();
5324 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5325 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5326 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5327 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5328 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5329 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5330}
5331
5332
5333CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5334 unsigned PieceIndex) {
5335 RefNamePieces Pieces;
5336
5337 switch (C.kind) {
5338 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005339 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5341 E->getQualifierLoc().getSourceRange());
5342 break;
5343
5344 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005345 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5347 E->getQualifierLoc().getSourceRange(),
5348 E->getOptionalExplicitTemplateArgs());
5349 break;
5350
5351 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005352 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005354 const Expr *Callee = OCE->getCallee();
5355 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 Callee = ICE->getSubExpr();
5357
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005358 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5360 DRE->getQualifierLoc().getSourceRange());
5361 }
5362 break;
5363
5364 default:
5365 break;
5366 }
5367
5368 if (Pieces.empty()) {
5369 if (PieceIndex == 0)
5370 return clang_getCursorExtent(C);
5371 } else if (PieceIndex < Pieces.size()) {
5372 SourceRange R = Pieces[PieceIndex];
5373 if (R.isValid())
5374 return cxloc::translateSourceRange(getCursorContext(C), R);
5375 }
5376
5377 return clang_getNullRange();
5378}
5379
5380void clang_enableStackTraces(void) {
5381 llvm::sys::PrintStackTraceOnErrorSignal();
5382}
5383
5384void clang_executeOnThread(void (*fn)(void*), void *user_data,
5385 unsigned stack_size) {
5386 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5387}
5388
5389} // end: extern "C"
5390
5391//===----------------------------------------------------------------------===//
5392// Token-based Operations.
5393//===----------------------------------------------------------------------===//
5394
5395/* CXToken layout:
5396 * int_data[0]: a CXTokenKind
5397 * int_data[1]: starting token location
5398 * int_data[2]: token length
5399 * int_data[3]: reserved
5400 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5401 * otherwise unused.
5402 */
5403extern "C" {
5404
5405CXTokenKind clang_getTokenKind(CXToken CXTok) {
5406 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5407}
5408
5409CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5410 switch (clang_getTokenKind(CXTok)) {
5411 case CXToken_Identifier:
5412 case CXToken_Keyword:
5413 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005414 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 ->getNameStart());
5416
5417 case CXToken_Literal: {
5418 // We have stashed the starting pointer in the ptr_data field. Use it.
5419 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005420 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 }
5422
5423 case CXToken_Punctuation:
5424 case CXToken_Comment:
5425 break;
5426 }
5427
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005428 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005429 LOG_BAD_TU(TU);
5430 return cxstring::createEmpty();
5431 }
5432
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 // We have to find the starting buffer pointer the hard way, by
5434 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005435 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005437 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005438
5439 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5440 std::pair<FileID, unsigned> LocInfo
5441 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5442 bool Invalid = false;
5443 StringRef Buffer
5444 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5445 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005446 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005447
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005448 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005449}
5450
5451CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005452 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005453 LOG_BAD_TU(TU);
5454 return clang_getNullLocation();
5455 }
5456
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005457 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 if (!CXXUnit)
5459 return clang_getNullLocation();
5460
5461 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5462 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5463}
5464
5465CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005467 LOG_BAD_TU(TU);
5468 return clang_getNullRange();
5469 }
5470
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005471 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 if (!CXXUnit)
5473 return clang_getNullRange();
5474
5475 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5476 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5477}
5478
5479static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5480 SmallVectorImpl<CXToken> &CXTokens) {
5481 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5482 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005483 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005485 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005486
5487 // Cannot tokenize across files.
5488 if (BeginLocInfo.first != EndLocInfo.first)
5489 return;
5490
5491 // Create a lexer
5492 bool Invalid = false;
5493 StringRef Buffer
5494 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5495 if (Invalid)
5496 return;
5497
5498 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5499 CXXUnit->getASTContext().getLangOpts(),
5500 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5501 Lex.SetCommentRetentionState(true);
5502
5503 // Lex tokens until we hit the end of the range.
5504 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5505 Token Tok;
5506 bool previousWasAt = false;
5507 do {
5508 // Lex the next token
5509 Lex.LexFromRawLexer(Tok);
5510 if (Tok.is(tok::eof))
5511 break;
5512
5513 // Initialize the CXToken.
5514 CXToken CXTok;
5515
5516 // - Common fields
5517 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5518 CXTok.int_data[2] = Tok.getLength();
5519 CXTok.int_data[3] = 0;
5520
5521 // - Kind-specific fields
5522 if (Tok.isLiteral()) {
5523 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005524 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 } else if (Tok.is(tok::raw_identifier)) {
5526 // Lookup the identifier to determine whether we have a keyword.
5527 IdentifierInfo *II
5528 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5529
5530 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5531 CXTok.int_data[0] = CXToken_Keyword;
5532 }
5533 else {
5534 CXTok.int_data[0] = Tok.is(tok::identifier)
5535 ? CXToken_Identifier
5536 : CXToken_Keyword;
5537 }
5538 CXTok.ptr_data = II;
5539 } else if (Tok.is(tok::comment)) {
5540 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005541 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 } else {
5543 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005544 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 }
5546 CXTokens.push_back(CXTok);
5547 previousWasAt = Tok.is(tok::at);
5548 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5549}
5550
5551void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5552 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005553 LOG_FUNC_SECTION {
5554 *Log << TU << ' ' << Range;
5555 }
5556
Guy Benyei11169dd2012-12-18 14:30:41 +00005557 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005558 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 if (NumTokens)
5560 *NumTokens = 0;
5561
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005562 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005563 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005564 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005565 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005566
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005567 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 if (!CXXUnit || !Tokens || !NumTokens)
5569 return;
5570
5571 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5572
5573 SourceRange R = cxloc::translateCXSourceRange(Range);
5574 if (R.isInvalid())
5575 return;
5576
5577 SmallVector<CXToken, 32> CXTokens;
5578 getTokens(CXXUnit, R, CXTokens);
5579
5580 if (CXTokens.empty())
5581 return;
5582
5583 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5584 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5585 *NumTokens = CXTokens.size();
5586}
5587
5588void clang_disposeTokens(CXTranslationUnit TU,
5589 CXToken *Tokens, unsigned NumTokens) {
5590 free(Tokens);
5591}
5592
5593} // end: extern "C"
5594
5595//===----------------------------------------------------------------------===//
5596// Token annotation APIs.
5597//===----------------------------------------------------------------------===//
5598
Guy Benyei11169dd2012-12-18 14:30:41 +00005599static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5600 CXCursor parent,
5601 CXClientData client_data);
5602static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5603 CXClientData client_data);
5604
5605namespace {
5606class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 CXToken *Tokens;
5608 CXCursor *Cursors;
5609 unsigned NumTokens;
5610 unsigned TokIdx;
5611 unsigned PreprocessingTokIdx;
5612 CursorVisitor AnnotateVis;
5613 SourceManager &SrcMgr;
5614 bool HasContextSensitiveKeywords;
5615
5616 struct PostChildrenInfo {
5617 CXCursor Cursor;
5618 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005619 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 unsigned BeforeChildrenTokenIdx;
5621 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005622 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005623
5624 CXToken &getTok(unsigned Idx) {
5625 assert(Idx < NumTokens);
5626 return Tokens[Idx];
5627 }
5628 const CXToken &getTok(unsigned Idx) const {
5629 assert(Idx < NumTokens);
5630 return Tokens[Idx];
5631 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 bool MoreTokens() const { return TokIdx < NumTokens; }
5633 unsigned NextToken() const { return TokIdx; }
5634 void AdvanceToken() { ++TokIdx; }
5635 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005636 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 }
5638 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005639 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 }
5641 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005642 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 }
5644
5645 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005646 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 SourceRange);
5648
5649public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005650 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005651 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005652 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005654 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 AnnotateTokensVisitor, this,
5656 /*VisitPreprocessorLast=*/true,
5657 /*VisitIncludedEntities=*/false,
5658 RegionOfInterest,
5659 /*VisitDeclsOnly=*/false,
5660 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005661 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 HasContextSensitiveKeywords(false) { }
5663
5664 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5665 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5666 bool postVisitChildren(CXCursor cursor);
5667 void AnnotateTokens();
5668
5669 /// \brief Determine whether the annotator saw any cursors that have
5670 /// context-sensitive keywords.
5671 bool hasContextSensitiveKeywords() const {
5672 return HasContextSensitiveKeywords;
5673 }
5674
5675 ~AnnotateTokensWorker() {
5676 assert(PostChildrenInfos.empty());
5677 }
5678};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005679}
Guy Benyei11169dd2012-12-18 14:30:41 +00005680
5681void AnnotateTokensWorker::AnnotateTokens() {
5682 // Walk the AST within the region of interest, annotating tokens
5683 // along the way.
5684 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005685}
Guy Benyei11169dd2012-12-18 14:30:41 +00005686
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005687static inline void updateCursorAnnotation(CXCursor &Cursor,
5688 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005689 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005691 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005692}
5693
5694/// \brief It annotates and advances tokens with a cursor until the comparison
5695//// between the cursor location and the source range is the same as
5696/// \arg compResult.
5697///
5698/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5699/// Pass RangeOverlap to annotate tokens inside a range.
5700void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5701 RangeComparisonResult compResult,
5702 SourceRange range) {
5703 while (MoreTokens()) {
5704 const unsigned I = NextToken();
5705 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005706 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5707 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005708
5709 SourceLocation TokLoc = GetTokenLoc(I);
5710 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 AdvanceToken();
5713 continue;
5714 }
5715 break;
5716 }
5717}
5718
5719/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005720/// \returns true if it advanced beyond all macro tokens, false otherwise.
5721bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 CXCursor updateC,
5723 RangeComparisonResult compResult,
5724 SourceRange range) {
5725 assert(MoreTokens());
5726 assert(isFunctionMacroToken(NextToken()) &&
5727 "Should be called only for macro arg tokens");
5728
5729 // This works differently than annotateAndAdvanceTokens; because expanded
5730 // macro arguments can have arbitrary translation-unit source order, we do not
5731 // advance the token index one by one until a token fails the range test.
5732 // We only advance once past all of the macro arg tokens if all of them
5733 // pass the range test. If one of them fails we keep the token index pointing
5734 // at the start of the macro arg tokens so that the failing token will be
5735 // annotated by a subsequent annotation try.
5736
5737 bool atLeastOneCompFail = false;
5738
5739 unsigned I = NextToken();
5740 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5741 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5742 if (TokLoc.isFileID())
5743 continue; // not macro arg token, it's parens or comma.
5744 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5745 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5746 Cursors[I] = updateC;
5747 } else
5748 atLeastOneCompFail = true;
5749 }
5750
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005751 if (atLeastOneCompFail)
5752 return false;
5753
5754 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5755 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005756}
5757
5758enum CXChildVisitResult
5759AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 SourceRange cursorRange = getRawCursorExtent(cursor);
5761 if (cursorRange.isInvalid())
5762 return CXChildVisit_Recurse;
5763
5764 if (!HasContextSensitiveKeywords) {
5765 // Objective-C properties can have context-sensitive keywords.
5766 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005767 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5769 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5770 }
5771 // Objective-C methods can have context-sensitive keywords.
5772 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5773 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005774 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5776 if (Method->getObjCDeclQualifier())
5777 HasContextSensitiveKeywords = true;
5778 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005779 for (const auto *P : Method->params()) {
5780 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 HasContextSensitiveKeywords = true;
5782 break;
5783 }
5784 }
5785 }
5786 }
5787 }
5788 // C++ methods can have context-sensitive keywords.
5789 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005790 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5792 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5793 HasContextSensitiveKeywords = true;
5794 }
5795 }
5796 // C++ classes can have context-sensitive keywords.
5797 else if (cursor.kind == CXCursor_StructDecl ||
5798 cursor.kind == CXCursor_ClassDecl ||
5799 cursor.kind == CXCursor_ClassTemplate ||
5800 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005801 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 if (D->hasAttr<FinalAttr>())
5803 HasContextSensitiveKeywords = true;
5804 }
5805 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005806
5807 // Don't override a property annotation with its getter/setter method.
5808 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5809 parent.kind == CXCursor_ObjCPropertyDecl)
5810 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005811
5812 if (clang_isPreprocessing(cursor.kind)) {
5813 // Items in the preprocessing record are kept separate from items in
5814 // declarations, so we keep a separate token index.
5815 unsigned SavedTokIdx = TokIdx;
5816 TokIdx = PreprocessingTokIdx;
5817
5818 // Skip tokens up until we catch up to the beginning of the preprocessing
5819 // entry.
5820 while (MoreTokens()) {
5821 const unsigned I = NextToken();
5822 SourceLocation TokLoc = GetTokenLoc(I);
5823 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5824 case RangeBefore:
5825 AdvanceToken();
5826 continue;
5827 case RangeAfter:
5828 case RangeOverlap:
5829 break;
5830 }
5831 break;
5832 }
5833
5834 // Look at all of the tokens within this range.
5835 while (MoreTokens()) {
5836 const unsigned I = NextToken();
5837 SourceLocation TokLoc = GetTokenLoc(I);
5838 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5839 case RangeBefore:
5840 llvm_unreachable("Infeasible");
5841 case RangeAfter:
5842 break;
5843 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005844 // For macro expansions, just note where the beginning of the macro
5845 // expansion occurs.
5846 if (cursor.kind == CXCursor_MacroExpansion) {
5847 if (TokLoc == cursorRange.getBegin())
5848 Cursors[I] = cursor;
5849 AdvanceToken();
5850 break;
5851 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005852 // We may have already annotated macro names inside macro definitions.
5853 if (Cursors[I].kind != CXCursor_MacroExpansion)
5854 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005855 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005856 continue;
5857 }
5858 break;
5859 }
5860
5861 // Save the preprocessing token index; restore the non-preprocessing
5862 // token index.
5863 PreprocessingTokIdx = TokIdx;
5864 TokIdx = SavedTokIdx;
5865 return CXChildVisit_Recurse;
5866 }
5867
5868 if (cursorRange.isInvalid())
5869 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005870
5871 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 const enum CXCursorKind K = clang_getCursorKind(parent);
5874 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005875 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5876 // Attributes are annotated out-of-order, skip tokens until we reach it.
5877 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 ? clang_getNullCursor() : parent;
5879
5880 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5881
5882 // Avoid having the cursor of an expression "overwrite" the annotation of the
5883 // variable declaration that it belongs to.
5884 // This can happen for C++ constructor expressions whose range generally
5885 // include the variable declaration, e.g.:
5886 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005887 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005888 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005889 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 const unsigned I = NextToken();
5891 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5892 E->getLocStart() == D->getLocation() &&
5893 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005894 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 AdvanceToken();
5896 }
5897 }
5898 }
5899
5900 // Before recursing into the children keep some state that we are going
5901 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5902 // extra work after the child nodes are visited.
5903 // Note that we don't call VisitChildren here to avoid traversing statements
5904 // code-recursively which can blow the stack.
5905
5906 PostChildrenInfo Info;
5907 Info.Cursor = cursor;
5908 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005909 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 Info.BeforeChildrenTokenIdx = NextToken();
5911 PostChildrenInfos.push_back(Info);
5912
5913 return CXChildVisit_Recurse;
5914}
5915
5916bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5917 if (PostChildrenInfos.empty())
5918 return false;
5919 const PostChildrenInfo &Info = PostChildrenInfos.back();
5920 if (!clang_equalCursors(Info.Cursor, cursor))
5921 return false;
5922
5923 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5924 const unsigned AfterChildren = NextToken();
5925 SourceRange cursorRange = Info.CursorRange;
5926
5927 // Scan the tokens that are at the end of the cursor, but are not captured
5928 // but the child cursors.
5929 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5930
5931 // Scan the tokens that are at the beginning of the cursor, but are not
5932 // capture by the child cursors.
5933 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5934 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5935 break;
5936
5937 Cursors[I] = cursor;
5938 }
5939
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005940 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5941 // encountered the attribute cursor.
5942 if (clang_isAttribute(cursor.kind))
5943 TokIdx = Info.BeforeReachingCursorIdx;
5944
Guy Benyei11169dd2012-12-18 14:30:41 +00005945 PostChildrenInfos.pop_back();
5946 return false;
5947}
5948
5949static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5950 CXCursor parent,
5951 CXClientData client_data) {
5952 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5953}
5954
5955static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5956 CXClientData client_data) {
5957 return static_cast<AnnotateTokensWorker*>(client_data)->
5958 postVisitChildren(cursor);
5959}
5960
5961namespace {
5962
5963/// \brief Uses the macro expansions in the preprocessing record to find
5964/// and mark tokens that are macro arguments. This info is used by the
5965/// AnnotateTokensWorker.
5966class MarkMacroArgTokensVisitor {
5967 SourceManager &SM;
5968 CXToken *Tokens;
5969 unsigned NumTokens;
5970 unsigned CurIdx;
5971
5972public:
5973 MarkMacroArgTokensVisitor(SourceManager &SM,
5974 CXToken *tokens, unsigned numTokens)
5975 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5976
5977 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5978 if (cursor.kind != CXCursor_MacroExpansion)
5979 return CXChildVisit_Continue;
5980
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005981 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 if (macroRange.getBegin() == macroRange.getEnd())
5983 return CXChildVisit_Continue; // it's not a function macro.
5984
5985 for (; CurIdx < NumTokens; ++CurIdx) {
5986 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5987 macroRange.getBegin()))
5988 break;
5989 }
5990
5991 if (CurIdx == NumTokens)
5992 return CXChildVisit_Break;
5993
5994 for (; CurIdx < NumTokens; ++CurIdx) {
5995 SourceLocation tokLoc = getTokenLoc(CurIdx);
5996 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5997 break;
5998
5999 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6000 }
6001
6002 if (CurIdx == NumTokens)
6003 return CXChildVisit_Break;
6004
6005 return CXChildVisit_Continue;
6006 }
6007
6008private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006009 CXToken &getTok(unsigned Idx) {
6010 assert(Idx < NumTokens);
6011 return Tokens[Idx];
6012 }
6013 const CXToken &getTok(unsigned Idx) const {
6014 assert(Idx < NumTokens);
6015 return Tokens[Idx];
6016 }
6017
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006019 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 }
6021
6022 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6023 // The third field is reserved and currently not used. Use it here
6024 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006025 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 }
6027};
6028
6029} // end anonymous namespace
6030
6031static CXChildVisitResult
6032MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6033 CXClientData client_data) {
6034 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6035 parent);
6036}
6037
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006038/// \brief Used by \c annotatePreprocessorTokens.
6039/// \returns true if lexing was finished, false otherwise.
6040static bool lexNext(Lexer &Lex, Token &Tok,
6041 unsigned &NextIdx, unsigned NumTokens) {
6042 if (NextIdx >= NumTokens)
6043 return true;
6044
6045 ++NextIdx;
6046 Lex.LexFromRawLexer(Tok);
6047 if (Tok.is(tok::eof))
6048 return true;
6049
6050 return false;
6051}
6052
Guy Benyei11169dd2012-12-18 14:30:41 +00006053static void annotatePreprocessorTokens(CXTranslationUnit TU,
6054 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006055 CXCursor *Cursors,
6056 CXToken *Tokens,
6057 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006058 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006059
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006060 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006061 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6062 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006063 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006064 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006065 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006066
6067 if (BeginLocInfo.first != EndLocInfo.first)
6068 return;
6069
6070 StringRef Buffer;
6071 bool Invalid = false;
6072 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6073 if (Buffer.empty() || Invalid)
6074 return;
6075
6076 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6077 CXXUnit->getASTContext().getLangOpts(),
6078 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6079 Buffer.end());
6080 Lex.SetCommentRetentionState(true);
6081
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006082 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 // Lex tokens in raw mode until we hit the end of the range, to avoid
6084 // entering #includes or expanding macros.
6085 while (true) {
6086 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006087 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6088 break;
6089 unsigned TokIdx = NextIdx-1;
6090 assert(Tok.getLocation() ==
6091 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006092
6093 reprocess:
6094 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006095 // We have found a preprocessing directive. Annotate the tokens
6096 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006097 //
6098 // FIXME: Some simple tests here could identify macro definitions and
6099 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006100
6101 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006102 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6103 break;
6104
Craig Topper69186e72014-06-08 08:38:04 +00006105 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006106 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006107 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6108 break;
6109
6110 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006111 IdentifierInfo &II =
6112 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006113 SourceLocation MappedTokLoc =
6114 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6115 MI = getMacroInfo(II, MappedTokLoc, TU);
6116 }
6117 }
6118
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006119 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006121 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6122 finished = true;
6123 break;
6124 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006125 // If we are in a macro definition, check if the token was ever a
6126 // macro name and annotate it if that's the case.
6127 if (MI) {
6128 SourceLocation SaveLoc = Tok.getLocation();
6129 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006130 MacroDefinitionRecord *MacroDef =
6131 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006132 Tok.setLocation(SaveLoc);
6133 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006134 Cursors[NextIdx - 1] =
6135 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006136 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006137 } while (!Tok.isAtStartOfLine());
6138
6139 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6140 assert(TokIdx <= LastIdx);
6141 SourceLocation EndLoc =
6142 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6143 CXCursor Cursor =
6144 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6145
6146 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006147 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006148
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006149 if (finished)
6150 break;
6151 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 }
6154}
6155
6156// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006157static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6158 CXToken *Tokens, unsigned NumTokens,
6159 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006160 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6162 setThreadBackgroundPriority();
6163
6164 // Determine the region of interest, which contains all of the tokens.
6165 SourceRange RegionOfInterest;
6166 RegionOfInterest.setBegin(
6167 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6168 RegionOfInterest.setEnd(
6169 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6170 Tokens[NumTokens-1])));
6171
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 // Relex the tokens within the source range to look for preprocessing
6173 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006174 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006175
6176 // If begin location points inside a macro argument, set it to the expansion
6177 // location so we can have the full context when annotating semantically.
6178 {
6179 SourceManager &SM = CXXUnit->getSourceManager();
6180 SourceLocation Loc =
6181 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6182 if (Loc.isMacroID())
6183 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6184 }
6185
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6187 // Search and mark tokens that are macro argument expansions.
6188 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6189 Tokens, NumTokens);
6190 CursorVisitor MacroArgMarker(TU,
6191 MarkMacroArgTokensVisitorDelegate, &Visitor,
6192 /*VisitPreprocessorLast=*/true,
6193 /*VisitIncludedEntities=*/false,
6194 RegionOfInterest);
6195 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6196 }
6197
6198 // Annotate all of the source locations in the region of interest that map to
6199 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006200 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201
6202 // FIXME: We use a ridiculous stack size here because the data-recursion
6203 // algorithm uses a large stack frame than the non-data recursive version,
6204 // and AnnotationTokensWorker currently transforms the data-recursion
6205 // algorithm back into a traditional recursion by explicitly calling
6206 // VisitChildren(). We will need to remove this explicit recursive call.
6207 W.AnnotateTokens();
6208
6209 // If we ran into any entities that involve context-sensitive keywords,
6210 // take another pass through the tokens to mark them as such.
6211 if (W.hasContextSensitiveKeywords()) {
6212 for (unsigned I = 0; I != NumTokens; ++I) {
6213 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6214 continue;
6215
6216 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6217 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006218 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6220 if (Property->getPropertyAttributesAsWritten() != 0 &&
6221 llvm::StringSwitch<bool>(II->getName())
6222 .Case("readonly", true)
6223 .Case("assign", true)
6224 .Case("unsafe_unretained", true)
6225 .Case("readwrite", true)
6226 .Case("retain", true)
6227 .Case("copy", true)
6228 .Case("nonatomic", true)
6229 .Case("atomic", true)
6230 .Case("getter", true)
6231 .Case("setter", true)
6232 .Case("strong", true)
6233 .Case("weak", true)
6234 .Default(false))
6235 Tokens[I].int_data[0] = CXToken_Keyword;
6236 }
6237 continue;
6238 }
6239
6240 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6241 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6242 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6243 if (llvm::StringSwitch<bool>(II->getName())
6244 .Case("in", true)
6245 .Case("out", true)
6246 .Case("inout", true)
6247 .Case("oneway", true)
6248 .Case("bycopy", true)
6249 .Case("byref", true)
6250 .Default(false))
6251 Tokens[I].int_data[0] = CXToken_Keyword;
6252 continue;
6253 }
6254
6255 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6256 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6257 Tokens[I].int_data[0] = CXToken_Keyword;
6258 continue;
6259 }
6260 }
6261 }
6262}
6263
6264extern "C" {
6265
6266void clang_annotateTokens(CXTranslationUnit TU,
6267 CXToken *Tokens, unsigned NumTokens,
6268 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006269 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006270 LOG_BAD_TU(TU);
6271 return;
6272 }
6273 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006274 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006275 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006276 }
6277
6278 LOG_FUNC_SECTION {
6279 *Log << TU << ' ';
6280 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6281 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6282 *Log << clang_getRange(bloc, eloc);
6283 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006284
6285 // Any token we don't specifically annotate will have a NULL cursor.
6286 CXCursor C = clang_getNullCursor();
6287 for (unsigned I = 0; I != NumTokens; ++I)
6288 Cursors[I] = C;
6289
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006290 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 if (!CXXUnit)
6292 return;
6293
6294 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006295
6296 auto AnnotateTokensImpl = [=]() {
6297 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6298 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006300 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6302 }
6303}
6304
6305} // end: extern "C"
6306
6307//===----------------------------------------------------------------------===//
6308// Operations for querying linkage of a cursor.
6309//===----------------------------------------------------------------------===//
6310
6311extern "C" {
6312CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6313 if (!clang_isDeclaration(cursor.kind))
6314 return CXLinkage_Invalid;
6315
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006316 const Decl *D = cxcursor::getCursorDecl(cursor);
6317 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006318 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006319 case NoLinkage:
6320 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 case InternalLinkage: return CXLinkage_Internal;
6322 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6323 case ExternalLinkage: return CXLinkage_External;
6324 };
6325
6326 return CXLinkage_Invalid;
6327}
6328} // end: extern "C"
6329
6330//===----------------------------------------------------------------------===//
6331// Operations for querying language of a cursor.
6332//===----------------------------------------------------------------------===//
6333
6334static CXLanguageKind getDeclLanguage(const Decl *D) {
6335 if (!D)
6336 return CXLanguage_C;
6337
6338 switch (D->getKind()) {
6339 default:
6340 break;
6341 case Decl::ImplicitParam:
6342 case Decl::ObjCAtDefsField:
6343 case Decl::ObjCCategory:
6344 case Decl::ObjCCategoryImpl:
6345 case Decl::ObjCCompatibleAlias:
6346 case Decl::ObjCImplementation:
6347 case Decl::ObjCInterface:
6348 case Decl::ObjCIvar:
6349 case Decl::ObjCMethod:
6350 case Decl::ObjCProperty:
6351 case Decl::ObjCPropertyImpl:
6352 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006353 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 return CXLanguage_ObjC;
6355 case Decl::CXXConstructor:
6356 case Decl::CXXConversion:
6357 case Decl::CXXDestructor:
6358 case Decl::CXXMethod:
6359 case Decl::CXXRecord:
6360 case Decl::ClassTemplate:
6361 case Decl::ClassTemplatePartialSpecialization:
6362 case Decl::ClassTemplateSpecialization:
6363 case Decl::Friend:
6364 case Decl::FriendTemplate:
6365 case Decl::FunctionTemplate:
6366 case Decl::LinkageSpec:
6367 case Decl::Namespace:
6368 case Decl::NamespaceAlias:
6369 case Decl::NonTypeTemplateParm:
6370 case Decl::StaticAssert:
6371 case Decl::TemplateTemplateParm:
6372 case Decl::TemplateTypeParm:
6373 case Decl::UnresolvedUsingTypename:
6374 case Decl::UnresolvedUsingValue:
6375 case Decl::Using:
6376 case Decl::UsingDirective:
6377 case Decl::UsingShadow:
6378 return CXLanguage_CPlusPlus;
6379 }
6380
6381 return CXLanguage_C;
6382}
6383
6384extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006385
6386static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6387 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6388 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006389
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006390 switch (D->getAvailability()) {
6391 case AR_Available:
6392 case AR_NotYetIntroduced:
6393 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006394 return getCursorAvailabilityForDecl(
6395 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006396 return CXAvailability_Available;
6397
6398 case AR_Deprecated:
6399 return CXAvailability_Deprecated;
6400
6401 case AR_Unavailable:
6402 return CXAvailability_NotAvailable;
6403 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006404
6405 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006406}
6407
Guy Benyei11169dd2012-12-18 14:30:41 +00006408enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6409 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006410 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6411 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006412
6413 return CXAvailability_Available;
6414}
6415
6416static CXVersion convertVersion(VersionTuple In) {
6417 CXVersion Out = { -1, -1, -1 };
6418 if (In.empty())
6419 return Out;
6420
6421 Out.Major = In.getMajor();
6422
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006423 Optional<unsigned> Minor = In.getMinor();
6424 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 Out.Minor = *Minor;
6426 else
6427 return Out;
6428
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006429 Optional<unsigned> Subminor = In.getSubminor();
6430 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 Out.Subminor = *Subminor;
6432
6433 return Out;
6434}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006435
6436static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6437 int *always_deprecated,
6438 CXString *deprecated_message,
6439 int *always_unavailable,
6440 CXString *unavailable_message,
6441 CXPlatformAvailability *availability,
6442 int availability_size) {
6443 bool HadAvailAttr = false;
6444 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006445 for (auto A : D->attrs()) {
6446 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006447 HadAvailAttr = true;
6448 if (always_deprecated)
6449 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006450 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006451 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006452 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006453 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006454 continue;
6455 }
6456
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006457 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006458 HadAvailAttr = true;
6459 if (always_unavailable)
6460 *always_unavailable = 1;
6461 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006462 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006463 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6464 }
6465 continue;
6466 }
6467
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006468 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006469 HadAvailAttr = true;
6470 if (N < availability_size) {
6471 availability[N].Platform
6472 = cxstring::createDup(Avail->getPlatform()->getName());
6473 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6474 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6475 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6476 availability[N].Unavailable = Avail->getUnavailable();
6477 availability[N].Message = cxstring::createDup(Avail->getMessage());
6478 }
6479 ++N;
6480 }
6481 }
6482
6483 if (!HadAvailAttr)
6484 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6485 return getCursorPlatformAvailabilityForDecl(
6486 cast<Decl>(EnumConst->getDeclContext()),
6487 always_deprecated,
6488 deprecated_message,
6489 always_unavailable,
6490 unavailable_message,
6491 availability,
6492 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006493
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006494 return N;
6495}
6496
Guy Benyei11169dd2012-12-18 14:30:41 +00006497int clang_getCursorPlatformAvailability(CXCursor cursor,
6498 int *always_deprecated,
6499 CXString *deprecated_message,
6500 int *always_unavailable,
6501 CXString *unavailable_message,
6502 CXPlatformAvailability *availability,
6503 int availability_size) {
6504 if (always_deprecated)
6505 *always_deprecated = 0;
6506 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006507 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006508 if (always_unavailable)
6509 *always_unavailable = 0;
6510 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006511 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006512
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 if (!clang_isDeclaration(cursor.kind))
6514 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006515
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006516 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006517 if (!D)
6518 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006519
6520 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6521 deprecated_message,
6522 always_unavailable,
6523 unavailable_message,
6524 availability,
6525 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006526}
6527
6528void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6529 clang_disposeString(availability->Platform);
6530 clang_disposeString(availability->Message);
6531}
6532
6533CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6534 if (clang_isDeclaration(cursor.kind))
6535 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6536
6537 return CXLanguage_Invalid;
6538}
6539
6540 /// \brief If the given cursor is the "templated" declaration
6541 /// descibing a class or function template, return the class or
6542 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006543static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006545 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006547 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6549 return FunTmpl;
6550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006551 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006552 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6553 return ClassTmpl;
6554
6555 return D;
6556}
6557
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006558
6559enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6560 StorageClass sc = SC_None;
6561 const Decl *D = getCursorDecl(C);
6562 if (D) {
6563 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6564 sc = FD->getStorageClass();
6565 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6566 sc = VD->getStorageClass();
6567 } else {
6568 return CX_SC_Invalid;
6569 }
6570 } else {
6571 return CX_SC_Invalid;
6572 }
6573 switch (sc) {
6574 case SC_None:
6575 return CX_SC_None;
6576 case SC_Extern:
6577 return CX_SC_Extern;
6578 case SC_Static:
6579 return CX_SC_Static;
6580 case SC_PrivateExtern:
6581 return CX_SC_PrivateExtern;
6582 case SC_OpenCLWorkGroupLocal:
6583 return CX_SC_OpenCLWorkGroupLocal;
6584 case SC_Auto:
6585 return CX_SC_Auto;
6586 case SC_Register:
6587 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006588 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006589 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006590}
6591
Guy Benyei11169dd2012-12-18 14:30:41 +00006592CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6593 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006594 if (const Decl *D = getCursorDecl(cursor)) {
6595 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 if (!DC)
6597 return clang_getNullCursor();
6598
6599 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6600 getCursorTU(cursor));
6601 }
6602 }
6603
6604 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006605 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006606 return MakeCXCursor(D, getCursorTU(cursor));
6607 }
6608
6609 return clang_getNullCursor();
6610}
6611
6612CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6613 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006614 if (const Decl *D = getCursorDecl(cursor)) {
6615 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 if (!DC)
6617 return clang_getNullCursor();
6618
6619 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6620 getCursorTU(cursor));
6621 }
6622 }
6623
6624 // FIXME: Note that we can't easily compute the lexical context of a
6625 // statement or expression, so we return nothing.
6626 return clang_getNullCursor();
6627}
6628
6629CXFile clang_getIncludedFile(CXCursor cursor) {
6630 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006631 return nullptr;
6632
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006633 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006634 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006635}
6636
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006637unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6638 if (C.kind != CXCursor_ObjCPropertyDecl)
6639 return CXObjCPropertyAttr_noattr;
6640
6641 unsigned Result = CXObjCPropertyAttr_noattr;
6642 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6643 ObjCPropertyDecl::PropertyAttributeKind Attr =
6644 PD->getPropertyAttributesAsWritten();
6645
6646#define SET_CXOBJCPROP_ATTR(A) \
6647 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6648 Result |= CXObjCPropertyAttr_##A
6649 SET_CXOBJCPROP_ATTR(readonly);
6650 SET_CXOBJCPROP_ATTR(getter);
6651 SET_CXOBJCPROP_ATTR(assign);
6652 SET_CXOBJCPROP_ATTR(readwrite);
6653 SET_CXOBJCPROP_ATTR(retain);
6654 SET_CXOBJCPROP_ATTR(copy);
6655 SET_CXOBJCPROP_ATTR(nonatomic);
6656 SET_CXOBJCPROP_ATTR(setter);
6657 SET_CXOBJCPROP_ATTR(atomic);
6658 SET_CXOBJCPROP_ATTR(weak);
6659 SET_CXOBJCPROP_ATTR(strong);
6660 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6661#undef SET_CXOBJCPROP_ATTR
6662
6663 return Result;
6664}
6665
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006666unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6667 if (!clang_isDeclaration(C.kind))
6668 return CXObjCDeclQualifier_None;
6669
6670 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6671 const Decl *D = getCursorDecl(C);
6672 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6673 QT = MD->getObjCDeclQualifier();
6674 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6675 QT = PD->getObjCDeclQualifier();
6676 if (QT == Decl::OBJC_TQ_None)
6677 return CXObjCDeclQualifier_None;
6678
6679 unsigned Result = CXObjCDeclQualifier_None;
6680 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6681 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6682 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6683 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6684 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6685 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6686
6687 return Result;
6688}
6689
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006690unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6691 if (!clang_isDeclaration(C.kind))
6692 return 0;
6693
6694 const Decl *D = getCursorDecl(C);
6695 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6696 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6697 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6698 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6699
6700 return 0;
6701}
6702
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006703unsigned clang_Cursor_isVariadic(CXCursor C) {
6704 if (!clang_isDeclaration(C.kind))
6705 return 0;
6706
6707 const Decl *D = getCursorDecl(C);
6708 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6709 return FD->isVariadic();
6710 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6711 return MD->isVariadic();
6712
6713 return 0;
6714}
6715
Guy Benyei11169dd2012-12-18 14:30:41 +00006716CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6717 if (!clang_isDeclaration(C.kind))
6718 return clang_getNullRange();
6719
6720 const Decl *D = getCursorDecl(C);
6721 ASTContext &Context = getCursorContext(C);
6722 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6723 if (!RC)
6724 return clang_getNullRange();
6725
6726 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6727}
6728
6729CXString clang_Cursor_getRawCommentText(CXCursor C) {
6730 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006731 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006732
6733 const Decl *D = getCursorDecl(C);
6734 ASTContext &Context = getCursorContext(C);
6735 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6736 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6737 StringRef();
6738
6739 // Don't duplicate the string because RawText points directly into source
6740 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006741 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006742}
6743
6744CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6745 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006746 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006747
6748 const Decl *D = getCursorDecl(C);
6749 const ASTContext &Context = getCursorContext(C);
6750 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6751
6752 if (RC) {
6753 StringRef BriefText = RC->getBriefText(Context);
6754
6755 // Don't duplicate the string because RawComment ensures that this memory
6756 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006757 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 }
6759
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006760 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006761}
6762
Guy Benyei11169dd2012-12-18 14:30:41 +00006763CXModule clang_Cursor_getModule(CXCursor C) {
6764 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006765 if (const ImportDecl *ImportD =
6766 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006767 return ImportD->getImportedModule();
6768 }
6769
Craig Topper69186e72014-06-08 08:38:04 +00006770 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006771}
6772
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006773CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6774 if (isNotUsableTU(TU)) {
6775 LOG_BAD_TU(TU);
6776 return nullptr;
6777 }
6778 if (!File)
6779 return nullptr;
6780 FileEntry *FE = static_cast<FileEntry *>(File);
6781
6782 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6783 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6784 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6785
Richard Smithfeb54b62014-10-23 02:01:19 +00006786 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006787}
6788
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006789CXFile clang_Module_getASTFile(CXModule CXMod) {
6790 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006791 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006792 Module *Mod = static_cast<Module*>(CXMod);
6793 return const_cast<FileEntry *>(Mod->getASTFile());
6794}
6795
Guy Benyei11169dd2012-12-18 14:30:41 +00006796CXModule clang_Module_getParent(CXModule CXMod) {
6797 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006798 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 Module *Mod = static_cast<Module*>(CXMod);
6800 return Mod->Parent;
6801}
6802
6803CXString clang_Module_getName(CXModule CXMod) {
6804 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006805 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006807 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006808}
6809
6810CXString clang_Module_getFullName(CXModule CXMod) {
6811 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006812 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006814 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006815}
6816
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006817int clang_Module_isSystem(CXModule CXMod) {
6818 if (!CXMod)
6819 return 0;
6820 Module *Mod = static_cast<Module*>(CXMod);
6821 return Mod->IsSystem;
6822}
6823
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006824unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6825 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006826 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006827 LOG_BAD_TU(TU);
6828 return 0;
6829 }
6830 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 return 0;
6832 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006833 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6834 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6835 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006836}
6837
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006838CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6839 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006840 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006841 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006842 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006843 }
6844 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006845 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006847 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006848
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006849 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6850 if (Index < TopHeaders.size())
6851 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006852
Craig Topper69186e72014-06-08 08:38:04 +00006853 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006854}
6855
6856} // end: extern "C"
6857
6858//===----------------------------------------------------------------------===//
6859// C++ AST instrospection.
6860//===----------------------------------------------------------------------===//
6861
6862extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006863unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6864 if (!clang_isDeclaration(C.kind))
6865 return 0;
6866
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006867 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006868 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006869 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006870 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6871}
6872
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006873unsigned clang_CXXMethod_isConst(CXCursor C) {
6874 if (!clang_isDeclaration(C.kind))
6875 return 0;
6876
6877 const Decl *D = cxcursor::getCursorDecl(C);
6878 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006879 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006880 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6881}
6882
Guy Benyei11169dd2012-12-18 14:30:41 +00006883unsigned clang_CXXMethod_isStatic(CXCursor C) {
6884 if (!clang_isDeclaration(C.kind))
6885 return 0;
6886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006887 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006888 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006889 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006890 return (Method && Method->isStatic()) ? 1 : 0;
6891}
6892
6893unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6894 if (!clang_isDeclaration(C.kind))
6895 return 0;
6896
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006897 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006898 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006899 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 return (Method && Method->isVirtual()) ? 1 : 0;
6901}
6902} // end: extern "C"
6903
6904//===----------------------------------------------------------------------===//
6905// Attribute introspection.
6906//===----------------------------------------------------------------------===//
6907
6908extern "C" {
6909CXType clang_getIBOutletCollectionType(CXCursor C) {
6910 if (C.kind != CXCursor_IBOutletCollectionAttr)
6911 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6912
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006913 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006914 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6915
6916 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6917}
6918} // end: extern "C"
6919
6920//===----------------------------------------------------------------------===//
6921// Inspecting memory usage.
6922//===----------------------------------------------------------------------===//
6923
6924typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6925
6926static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6927 enum CXTUResourceUsageKind k,
6928 unsigned long amount) {
6929 CXTUResourceUsageEntry entry = { k, amount };
6930 entries.push_back(entry);
6931}
6932
6933extern "C" {
6934
6935const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6936 const char *str = "";
6937 switch (kind) {
6938 case CXTUResourceUsage_AST:
6939 str = "ASTContext: expressions, declarations, and types";
6940 break;
6941 case CXTUResourceUsage_Identifiers:
6942 str = "ASTContext: identifiers";
6943 break;
6944 case CXTUResourceUsage_Selectors:
6945 str = "ASTContext: selectors";
6946 break;
6947 case CXTUResourceUsage_GlobalCompletionResults:
6948 str = "Code completion: cached global results";
6949 break;
6950 case CXTUResourceUsage_SourceManagerContentCache:
6951 str = "SourceManager: content cache allocator";
6952 break;
6953 case CXTUResourceUsage_AST_SideTables:
6954 str = "ASTContext: side tables";
6955 break;
6956 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6957 str = "SourceManager: malloc'ed memory buffers";
6958 break;
6959 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6960 str = "SourceManager: mmap'ed memory buffers";
6961 break;
6962 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6963 str = "ExternalASTSource: malloc'ed memory buffers";
6964 break;
6965 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6966 str = "ExternalASTSource: mmap'ed memory buffers";
6967 break;
6968 case CXTUResourceUsage_Preprocessor:
6969 str = "Preprocessor: malloc'ed memory";
6970 break;
6971 case CXTUResourceUsage_PreprocessingRecord:
6972 str = "Preprocessor: PreprocessingRecord";
6973 break;
6974 case CXTUResourceUsage_SourceManager_DataStructures:
6975 str = "SourceManager: data structures and tables";
6976 break;
6977 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6978 str = "Preprocessor: header search tables";
6979 break;
6980 }
6981 return str;
6982}
6983
6984CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006985 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006986 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006987 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006988 return usage;
6989 }
6990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006991 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006992 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006993 ASTContext &astContext = astUnit->getASTContext();
6994
6995 // How much memory is used by AST nodes and types?
6996 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6997 (unsigned long) astContext.getASTAllocatedMemory());
6998
6999 // How much memory is used by identifiers?
7000 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7001 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7002
7003 // How much memory is used for selectors?
7004 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7005 (unsigned long) astContext.Selectors.getTotalMemory());
7006
7007 // How much memory is used by ASTContext's side tables?
7008 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7009 (unsigned long) astContext.getSideTableAllocatedMemory());
7010
7011 // How much memory is used for caching global code completion results?
7012 unsigned long completionBytes = 0;
7013 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007014 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 completionBytes = completionAllocator->getTotalMemory();
7016 }
7017 createCXTUResourceUsageEntry(*entries,
7018 CXTUResourceUsage_GlobalCompletionResults,
7019 completionBytes);
7020
7021 // How much memory is being used by SourceManager's content cache?
7022 createCXTUResourceUsageEntry(*entries,
7023 CXTUResourceUsage_SourceManagerContentCache,
7024 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7025
7026 // How much memory is being used by the MemoryBuffer's in SourceManager?
7027 const SourceManager::MemoryBufferSizes &srcBufs =
7028 astUnit->getSourceManager().getMemoryBufferSizes();
7029
7030 createCXTUResourceUsageEntry(*entries,
7031 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7032 (unsigned long) srcBufs.malloc_bytes);
7033 createCXTUResourceUsageEntry(*entries,
7034 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7035 (unsigned long) srcBufs.mmap_bytes);
7036 createCXTUResourceUsageEntry(*entries,
7037 CXTUResourceUsage_SourceManager_DataStructures,
7038 (unsigned long) astContext.getSourceManager()
7039 .getDataStructureSizes());
7040
7041 // How much memory is being used by the ExternalASTSource?
7042 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7043 const ExternalASTSource::MemoryBufferSizes &sizes =
7044 esrc->getMemoryBufferSizes();
7045
7046 createCXTUResourceUsageEntry(*entries,
7047 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7048 (unsigned long) sizes.malloc_bytes);
7049 createCXTUResourceUsageEntry(*entries,
7050 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7051 (unsigned long) sizes.mmap_bytes);
7052 }
7053
7054 // How much memory is being used by the Preprocessor?
7055 Preprocessor &pp = astUnit->getPreprocessor();
7056 createCXTUResourceUsageEntry(*entries,
7057 CXTUResourceUsage_Preprocessor,
7058 pp.getTotalMemory());
7059
7060 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7061 createCXTUResourceUsageEntry(*entries,
7062 CXTUResourceUsage_PreprocessingRecord,
7063 pRec->getTotalMemory());
7064 }
7065
7066 createCXTUResourceUsageEntry(*entries,
7067 CXTUResourceUsage_Preprocessor_HeaderSearch,
7068 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007069
Guy Benyei11169dd2012-12-18 14:30:41 +00007070 CXTUResourceUsage usage = { (void*) entries.get(),
7071 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007072 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007073 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007074 return usage;
7075}
7076
7077void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7078 if (usage.data)
7079 delete (MemUsageEntries*) usage.data;
7080}
7081
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007082CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7083 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007084 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007085 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007086
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007087 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007088 LOG_BAD_TU(TU);
7089 return skipped;
7090 }
7091
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007092 if (!file)
7093 return skipped;
7094
7095 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7096 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7097 if (!ppRec)
7098 return skipped;
7099
7100 ASTContext &Ctx = astUnit->getASTContext();
7101 SourceManager &sm = Ctx.getSourceManager();
7102 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7103 FileID wantedFileID = sm.translateFile(fileEntry);
7104
7105 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7106 std::vector<SourceRange> wantedRanges;
7107 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7108 i != ei; ++i) {
7109 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7110 wantedRanges.push_back(*i);
7111 }
7112
7113 skipped->count = wantedRanges.size();
7114 skipped->ranges = new CXSourceRange[skipped->count];
7115 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7116 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7117
7118 return skipped;
7119}
7120
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007121void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7122 if (ranges) {
7123 delete[] ranges->ranges;
7124 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007125 }
7126}
7127
Guy Benyei11169dd2012-12-18 14:30:41 +00007128} // end extern "C"
7129
7130void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7131 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7132 for (unsigned I = 0; I != Usage.numEntries; ++I)
7133 fprintf(stderr, " %s: %lu\n",
7134 clang_getTUResourceUsageName(Usage.entries[I].kind),
7135 Usage.entries[I].amount);
7136
7137 clang_disposeCXTUResourceUsage(Usage);
7138}
7139
7140//===----------------------------------------------------------------------===//
7141// Misc. utility functions.
7142//===----------------------------------------------------------------------===//
7143
7144/// Default to using an 8 MB stack size on "safety" threads.
7145static unsigned SafetyStackThreadSize = 8 << 20;
7146
7147namespace clang {
7148
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007149bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007150 unsigned Size) {
7151 if (!Size)
7152 Size = GetSafetyThreadStackSize();
7153 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007154 return CRC.RunSafelyOnThread(Fn, Size);
7155 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007156}
7157
7158unsigned GetSafetyThreadStackSize() {
7159 return SafetyStackThreadSize;
7160}
7161
7162void SetSafetyThreadStackSize(unsigned Value) {
7163 SafetyStackThreadSize = Value;
7164}
7165
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007166}
Guy Benyei11169dd2012-12-18 14:30:41 +00007167
7168void clang::setThreadBackgroundPriority() {
7169 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7170 return;
7171
Alp Toker1a86ad22014-07-06 06:24:00 +00007172#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007173 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7174#endif
7175}
7176
7177void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7178 if (!Unit)
7179 return;
7180
7181 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7182 DEnd = Unit->stored_diag_end();
7183 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007184 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007185 CXString Msg = clang_formatDiagnostic(&Diag,
7186 clang_defaultDiagnosticDisplayOptions());
7187 fprintf(stderr, "%s\n", clang_getCString(Msg));
7188 clang_disposeString(Msg);
7189 }
7190#ifdef LLVM_ON_WIN32
7191 // On Windows, force a flush, since there may be multiple copies of
7192 // stderr and stdout in the file system, all with different buffers
7193 // but writing to the same device.
7194 fflush(stderr);
7195#endif
7196}
7197
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007198MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7199 SourceLocation MacroDefLoc,
7200 CXTranslationUnit TU){
7201 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007202 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007203 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007204 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007205
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007206 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007207 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007208 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007209 if (MD) {
7210 for (MacroDirective::DefInfo
7211 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7212 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7213 return Def.getMacroInfo();
7214 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007215 }
7216
Craig Topper69186e72014-06-08 08:38:04 +00007217 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007218}
7219
Richard Smith66a81862015-05-04 02:25:31 +00007220const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007221 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007222 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007223 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224 const IdentifierInfo *II = MacroDef->getName();
7225 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007226 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007227
7228 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7229}
7230
Richard Smith66a81862015-05-04 02:25:31 +00007231MacroDefinitionRecord *
7232cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7233 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007235 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007236 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007237 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007238
7239 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007240 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7242 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007243 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007244
7245 // Check that the token is inside the definition and not its argument list.
7246 SourceManager &SM = Unit->getSourceManager();
7247 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007248 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007249 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007250 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251
7252 Preprocessor &PP = Unit->getPreprocessor();
7253 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7254 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007255 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007256
Alp Toker2d57cea2014-05-17 04:53:25 +00007257 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007258 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007259 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007260
7261 // Check that the identifier is not one of the macro arguments.
7262 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007263 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264
Richard Smith20e883e2015-04-29 23:20:19 +00007265 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007266 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007267 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007269 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270}
7271
Richard Smith66a81862015-05-04 02:25:31 +00007272MacroDefinitionRecord *
7273cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7274 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007275 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007276 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007277
7278 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007279 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007280 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007281 Preprocessor &PP = Unit->getPreprocessor();
7282 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007283 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007284 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7285 Token Tok;
7286 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007287 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007288
7289 return checkForMacroInMacroDefinition(MI, Tok, TU);
7290}
7291
Guy Benyei11169dd2012-12-18 14:30:41 +00007292extern "C" {
7293
7294CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007295 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007296}
7297
7298} // end: extern "C"
7299
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007300Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7301 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007302 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007303 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007304 if (Unit->isMainFileAST())
7305 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007306 return *this;
7307 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007308 } else {
7309 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007310 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007311 return *this;
7312}
7313
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007314Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7315 *this << FE->getName();
7316 return *this;
7317}
7318
7319Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7320 CXString cursorName = clang_getCursorDisplayName(cursor);
7321 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7322 clang_disposeString(cursorName);
7323 return *this;
7324}
7325
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007326Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7327 CXFile File;
7328 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007329 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330 CXString FileName = clang_getFileName(File);
7331 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7332 clang_disposeString(FileName);
7333 return *this;
7334}
7335
7336Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7337 CXSourceLocation BLoc = clang_getRangeStart(range);
7338 CXSourceLocation ELoc = clang_getRangeEnd(range);
7339
7340 CXFile BFile;
7341 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007342 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007343
7344 CXFile EFile;
7345 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007346 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007347
7348 CXString BFileName = clang_getFileName(BFile);
7349 if (BFile == EFile) {
7350 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7351 BLine, BColumn, ELine, EColumn);
7352 } else {
7353 CXString EFileName = clang_getFileName(EFile);
7354 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7355 BLine, BColumn)
7356 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7357 ELine, EColumn);
7358 clang_disposeString(EFileName);
7359 }
7360 clang_disposeString(BFileName);
7361 return *this;
7362}
7363
7364Logger &cxindex::Logger::operator<<(CXString Str) {
7365 *this << clang_getCString(Str);
7366 return *this;
7367}
7368
7369Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7370 LogOS << Fmt;
7371 return *this;
7372}
7373
Chandler Carruth37ad2582014-06-27 15:14:39 +00007374static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7375
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007376cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007377 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007378
7379 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7380
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007381 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007382 OS << "[libclang:" << Name << ':';
7383
Alp Toker1a86ad22014-07-06 06:24:00 +00007384#ifdef USE_DARWIN_THREADS
7385 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007386 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7387 OS << tid << ':';
7388#endif
7389
7390 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7391 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007392 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007393
7394 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007395 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007396 OS << "--------------------------------------------------\n";
7397 }
7398}