blob: b9a56833a8116c1c6d3c73ae1651ad7aeedcad29 [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
Alexander Musman8bd31e62014-05-27 15:12:19 +00002022void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2023 Visitor->AddStmt(C->getNumForLoops());
2024}
2025
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002026void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002027
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002028void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2029
Alexey Bataev56dafe82014-06-20 07:16:17 +00002030void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2031 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002032 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002033}
2034
Alexey Bataev10e775f2015-07-30 11:36:16 +00002035void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2036 Visitor->AddStmt(C->getNumForLoops());
2037}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002038
Alexey Bataev236070f2014-06-20 11:19:47 +00002039void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2040
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002041void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2042
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002043void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2044
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002045void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2046
Alexey Bataevdea47612014-07-23 07:46:59 +00002047void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2048
Alexey Bataev67a4f222014-07-23 10:25:33 +00002049void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2050
Alexey Bataev459dec02014-07-24 06:46:57 +00002051void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2052
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002053void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2054
Alexey Bataev756c1962013-09-24 03:17:45 +00002055template<typename T>
2056void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002057 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002058 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002059 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002060}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002061
2062void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002063 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002064 for (const auto *E : C->private_copies()) {
2065 Visitor->AddStmt(E);
2066 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002067}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002068void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2069 const OMPFirstprivateClause *C) {
2070 VisitOMPClauseList(C);
2071}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002072void OMPClauseEnqueue::VisitOMPLastprivateClause(
2073 const OMPLastprivateClause *C) {
2074 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002075 for (auto *E : C->private_copies()) {
2076 Visitor->AddStmt(E);
2077 }
2078 for (auto *E : C->source_exprs()) {
2079 Visitor->AddStmt(E);
2080 }
2081 for (auto *E : C->destination_exprs()) {
2082 Visitor->AddStmt(E);
2083 }
2084 for (auto *E : C->assignment_ops()) {
2085 Visitor->AddStmt(E);
2086 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002087}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002088void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002089 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002090}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002091void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2092 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002093 for (auto *E : C->lhs_exprs()) {
2094 Visitor->AddStmt(E);
2095 }
2096 for (auto *E : C->rhs_exprs()) {
2097 Visitor->AddStmt(E);
2098 }
2099 for (auto *E : C->reduction_ops()) {
2100 Visitor->AddStmt(E);
2101 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002102}
Alexander Musman8dba6642014-04-22 13:09:42 +00002103void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2104 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002105 for (const auto *E : C->inits()) {
2106 Visitor->AddStmt(E);
2107 }
2108 for (const auto *E : C->updates()) {
2109 Visitor->AddStmt(E);
2110 }
2111 for (const auto *E : C->finals()) {
2112 Visitor->AddStmt(E);
2113 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002114 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002115 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002116}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002117void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2118 VisitOMPClauseList(C);
2119 Visitor->AddStmt(C->getAlignment());
2120}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002121void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2122 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002123 for (auto *E : C->source_exprs()) {
2124 Visitor->AddStmt(E);
2125 }
2126 for (auto *E : C->destination_exprs()) {
2127 Visitor->AddStmt(E);
2128 }
2129 for (auto *E : C->assignment_ops()) {
2130 Visitor->AddStmt(E);
2131 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002132}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002133void
2134OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2135 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002136 for (auto *E : C->source_exprs()) {
2137 Visitor->AddStmt(E);
2138 }
2139 for (auto *E : C->destination_exprs()) {
2140 Visitor->AddStmt(E);
2141 }
2142 for (auto *E : C->assignment_ops()) {
2143 Visitor->AddStmt(E);
2144 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002145}
Alexey Bataev6125da92014-07-21 11:26:11 +00002146void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2147 VisitOMPClauseList(C);
2148}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002149void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2150 VisitOMPClauseList(C);
2151}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002152}
Alexey Bataev756c1962013-09-24 03:17:45 +00002153
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002154void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2155 unsigned size = WL.size();
2156 OMPClauseEnqueue Visitor(this);
2157 Visitor.Visit(S);
2158 if (size == WL.size())
2159 return;
2160 // Now reverse the entries we just added. This will match the DFS
2161 // ordering performed by the worklist.
2162 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2163 std::reverse(I, E);
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 AddDecl(B->getBlockDecl());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(E);
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002176 for (auto &I : llvm::reverse(S->body()))
2177 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002178}
2179void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddStmt(S->getSubStmt());
2182 AddDeclarationNameInfo(S);
2183 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2184 AddNestedNameSpecifierLoc(QualifierLoc);
2185}
2186
2187void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2190 AddDeclarationNameInfo(E);
2191 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2192 AddNestedNameSpecifierLoc(QualifierLoc);
2193 if (!E->isImplicitAccess())
2194 AddStmt(E->getBase());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 // Enqueue the initializer , if any.
2198 AddStmt(E->getInitializer());
2199 // Enqueue the array size, if any.
2200 AddStmt(E->getArraySize());
2201 // Enqueue the allocated type.
2202 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2203 // Enqueue the placement arguments.
2204 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2205 AddStmt(E->getPlacementArg(I-1));
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2209 AddStmt(CE->getArg(I-1));
2210 AddStmt(CE->getCallee());
2211 AddStmt(CE->getArg(0));
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2214 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 // Visit the name of the type being destroyed.
2216 AddTypeLoc(E->getDestroyedTypeInfo());
2217 // Visit the scope type that looks disturbingly like the nested-name-specifier
2218 // but isn't.
2219 AddTypeLoc(E->getScopeTypeInfo());
2220 // Visit the nested-name-specifier.
2221 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2222 AddNestedNameSpecifierLoc(QualifierLoc);
2223 // Visit base expression.
2224 AddStmt(E->getBase());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2227 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddTypeLoc(E->getTypeSourceInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2231 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 EnqueueChildren(E);
2233 AddTypeLoc(E->getTypeSourceInfo());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 EnqueueChildren(E);
2237 if (E->isTypeOperand())
2238 AddTypeLoc(E->getTypeOperandSourceInfo());
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2242 const CXXUnresolvedConstructExpr *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::VisitCXXUuidofExpr(const CXXUuidofExpr *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::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 EnqueueChildren(S);
2254 AddDecl(S->getExceptionDecl());
2255}
2256
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002257void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002258 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002259 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002260 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 if (DR->hasExplicitTemplateArgs()) {
2265 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2266 }
2267 WL.push_back(DeclRefExprParts(DR, Parent));
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2270 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2272 AddDeclarationNameInfo(E);
2273 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 unsigned size = WL.size();
2277 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002278 for (const auto *D : S->decls()) {
2279 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 isFirst = false;
2281 }
2282 if (size == WL.size())
2283 return;
2284 // Now reverse the entries we just added. This will match the DFS
2285 // ordering performed by the worklist.
2286 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2287 std::reverse(I, E);
2288}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 D = E->designators_rbegin(), DEnd = E->designators_rend();
2293 D != DEnd; ++D) {
2294 if (D->isFieldDesignator()) {
2295 if (FieldDecl *Field = D->getField())
2296 AddMemberRef(Field, D->getFieldLoc());
2297 continue;
2298 }
2299 if (D->isArrayDesignator()) {
2300 AddStmt(E->getArrayIndex(*D));
2301 continue;
2302 }
2303 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2304 AddStmt(E->getArrayRangeEnd(*D));
2305 AddStmt(E->getArrayRangeStart(*D));
2306 }
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 EnqueueChildren(E);
2310 AddTypeLoc(E->getTypeInfoAsWritten());
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 AddStmt(FS->getBody());
2314 AddStmt(FS->getInc());
2315 AddStmt(FS->getCond());
2316 AddDecl(FS->getConditionVariable());
2317 AddStmt(FS->getInit());
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 AddStmt(If->getElse());
2324 AddStmt(If->getThen());
2325 AddStmt(If->getCond());
2326 AddDecl(If->getConditionVariable());
2327}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 // We care about the syntactic form of the initializer list, only.
2330 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2331 IE = Syntactic;
2332 EnqueueChildren(IE);
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 WL.push_back(MemberExprParts(M, Parent));
2336
2337 // If the base of the member access expression is an implicit 'this', don't
2338 // visit it.
2339 // FIXME: If we ever want to show these implicit accesses, this will be
2340 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002341 if (M->isImplicitAccess())
2342 return;
2343
2344 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2345 // real field that that we are interested in.
2346 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2347 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2348 if (FD->isAnonymousStructOrUnion()) {
2349 AddStmt(SubME->getBase());
2350 return;
2351 }
2352 }
2353 }
2354
2355 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002356}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 AddTypeLoc(E->getEncodedTypeSourceInfo());
2359}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 EnqueueChildren(M);
2362 AddTypeLoc(M->getClassReceiverTypeInfo());
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 // Visit the components of the offsetof expression.
2366 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2367 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2368 const OffsetOfNode &Node = E->getComponent(I-1);
2369 switch (Node.getKind()) {
2370 case OffsetOfNode::Array:
2371 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2372 break;
2373 case OffsetOfNode::Field:
2374 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2375 break;
2376 case OffsetOfNode::Identifier:
2377 case OffsetOfNode::Base:
2378 continue;
2379 }
2380 }
2381 // Visit the type into which we're computing the offset.
2382 AddTypeLoc(E->getTypeSourceInfo());
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2386 WL.push_back(OverloadExprParts(E, Parent));
2387}
2388void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 EnqueueChildren(E);
2391 if (E->isArgumentType())
2392 AddTypeLoc(E->getArgumentTypeInfo());
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 EnqueueChildren(S);
2396}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 AddStmt(S->getBody());
2399 AddStmt(S->getCond());
2400 AddDecl(S->getConditionVariable());
2401}
2402
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 AddStmt(W->getBody());
2405 AddStmt(W->getCond());
2406 AddDecl(W->getConditionVariable());
2407}
2408
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 for (unsigned I = E->getNumArgs(); I > 0; --I)
2411 AddTypeLoc(E->getArg(I-1));
2412}
2413
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 AddTypeLoc(E->getQueriedTypeSourceInfo());
2416}
2417
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 EnqueueChildren(E);
2420}
2421
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 VisitOverloadExpr(U);
2424 if (!U->isImplicitAccess())
2425 AddStmt(U->getBase());
2426}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 AddStmt(E->getSubExpr());
2429 AddTypeLoc(E->getWrittenTypeInfo());
2430}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 WL.push_back(SizeOfPackExprParts(E, Parent));
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 // If the opaque value has a source expression, just transparently
2436 // visit that. This is useful for (e.g.) pseudo-object expressions.
2437 if (Expr *SourceExpr = E->getSourceExpr())
2438 return Visit(SourceExpr);
2439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 AddStmt(E->getBody());
2442 WL.push_back(LambdaExprParts(E, Parent));
2443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 // Treat the expression like its syntactic form.
2446 Visit(E->getSyntacticForm());
2447}
2448
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002449void EnqueueVisitor::VisitOMPExecutableDirective(
2450 const OMPExecutableDirective *D) {
2451 EnqueueChildren(D);
2452 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2453 E = D->clauses().end();
2454 I != E; ++I)
2455 EnqueueChildren(*I);
2456}
2457
Alexander Musman3aaab662014-08-19 11:27:13 +00002458void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2459 VisitOMPExecutableDirective(D);
2460}
2461
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002462void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2463 VisitOMPExecutableDirective(D);
2464}
2465
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002466void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002467 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002468}
2469
Alexey Bataevf29276e2014-06-18 04:14:57 +00002470void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002471 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002472}
2473
Alexander Musmanf82886e2014-09-18 05:12:34 +00002474void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2475 VisitOMPLoopDirective(D);
2476}
2477
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002478void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2479 VisitOMPExecutableDirective(D);
2480}
2481
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002482void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2483 VisitOMPExecutableDirective(D);
2484}
2485
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002486void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2487 VisitOMPExecutableDirective(D);
2488}
2489
Alexander Musman80c22892014-07-17 08:54:58 +00002490void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2491 VisitOMPExecutableDirective(D);
2492}
2493
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002494void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496 AddDeclarationNameInfo(D);
2497}
2498
Alexey Bataev4acb8592014-07-07 13:01:15 +00002499void
2500EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002501 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002502}
2503
Alexander Musmane4e893b2014-09-23 09:33:00 +00002504void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2505 const OMPParallelForSimdDirective *D) {
2506 VisitOMPLoopDirective(D);
2507}
2508
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002509void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2510 const OMPParallelSectionsDirective *D) {
2511 VisitOMPExecutableDirective(D);
2512}
2513
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002514void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev68446b72014-07-18 07:47:19 +00002518void
2519EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002523void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525}
2526
Alexey Bataev2df347a2014-07-18 10:17:07 +00002527void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2528 VisitOMPExecutableDirective(D);
2529}
2530
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002531void EnqueueVisitor::VisitOMPTaskgroupDirective(
2532 const OMPTaskgroupDirective *D) {
2533 VisitOMPExecutableDirective(D);
2534}
2535
Alexey Bataev6125da92014-07-21 11:26:11 +00002536void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2537 VisitOMPExecutableDirective(D);
2538}
2539
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002540void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2541 VisitOMPExecutableDirective(D);
2542}
2543
Alexey Bataev0162e452014-07-22 10:10:35 +00002544void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2545 VisitOMPExecutableDirective(D);
2546}
2547
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002548void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2549 VisitOMPExecutableDirective(D);
2550}
2551
Michael Wong65f367f2015-07-21 13:44:28 +00002552void EnqueueVisitor::VisitOMPTargetDataDirective(const
2553 OMPTargetDataDirective *D) {
2554 VisitOMPExecutableDirective(D);
2555}
2556
Alexey Bataev13314bf2014-10-09 04:18:56 +00002557void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2558 VisitOMPExecutableDirective(D);
2559}
2560
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002561void EnqueueVisitor::VisitOMPCancellationPointDirective(
2562 const OMPCancellationPointDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataev80909872015-07-02 11:25:17 +00002566void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002570void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002571 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2572}
2573
2574bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2575 if (RegionOfInterest.isValid()) {
2576 SourceRange Range = getRawCursorExtent(C);
2577 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2578 return false;
2579 }
2580 return true;
2581}
2582
2583bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2584 while (!WL.empty()) {
2585 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002586 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002587
2588 // Set the Parent field, then back to its old value once we're done.
2589 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2590
2591 switch (LI.getKind()) {
2592 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 if (!D)
2595 continue;
2596
2597 // For now, perform default visitation for Decls.
2598 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2599 cast<DeclVisit>(&LI)->isFirst())))
2600 return true;
2601
2602 continue;
2603 }
2604 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2605 const ASTTemplateArgumentListInfo *ArgList =
2606 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2607 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2608 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2609 Arg != ArgEnd; ++Arg) {
2610 if (VisitTemplateArgumentLoc(*Arg))
2611 return true;
2612 }
2613 continue;
2614 }
2615 case VisitorJob::TypeLocVisitKind: {
2616 // Perform default visitation for TypeLocs.
2617 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2618 return true;
2619 continue;
2620 }
2621 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002622 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002623 if (LabelStmt *stmt = LS->getStmt()) {
2624 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2625 TU))) {
2626 return true;
2627 }
2628 }
2629 continue;
2630 }
2631
2632 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2633 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2634 if (VisitNestedNameSpecifierLoc(V->get()))
2635 return true;
2636 continue;
2637 }
2638
2639 case VisitorJob::DeclarationNameInfoVisitKind: {
2640 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2641 ->get()))
2642 return true;
2643 continue;
2644 }
2645 case VisitorJob::MemberRefVisitKind: {
2646 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2647 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2648 return true;
2649 continue;
2650 }
2651 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002652 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002653 if (!S)
2654 continue;
2655
2656 // Update the current cursor.
2657 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2658 if (!IsInRegionOfInterest(Cursor))
2659 continue;
2660 switch (Visitor(Cursor, Parent, ClientData)) {
2661 case CXChildVisit_Break: return true;
2662 case CXChildVisit_Continue: break;
2663 case CXChildVisit_Recurse:
2664 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002665 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002666 EnqueueWorkList(WL, S);
2667 break;
2668 }
2669 continue;
2670 }
2671 case VisitorJob::MemberExprPartsKind: {
2672 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002673 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002674
2675 // Visit the nested-name-specifier
2676 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2677 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2678 return true;
2679
2680 // Visit the declaration name.
2681 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2682 return true;
2683
2684 // Visit the explicitly-specified template arguments, if any.
2685 if (M->hasExplicitTemplateArgs()) {
2686 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2687 *ArgEnd = Arg + M->getNumTemplateArgs();
2688 Arg != ArgEnd; ++Arg) {
2689 if (VisitTemplateArgumentLoc(*Arg))
2690 return true;
2691 }
2692 }
2693 continue;
2694 }
2695 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002696 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 // Visit nested-name-specifier, if present.
2698 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2699 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2700 return true;
2701 // Visit declaration name.
2702 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2703 return true;
2704 continue;
2705 }
2706 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002707 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 // Visit the nested-name-specifier.
2709 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2710 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2711 return true;
2712 // Visit the declaration name.
2713 if (VisitDeclarationNameInfo(O->getNameInfo()))
2714 return true;
2715 // Visit the overloaded declaration reference.
2716 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2717 return true;
2718 continue;
2719 }
2720 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002721 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002722 NamedDecl *Pack = E->getPack();
2723 if (isa<TemplateTypeParmDecl>(Pack)) {
2724 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2725 E->getPackLoc(), TU)))
2726 return true;
2727
2728 continue;
2729 }
2730
2731 if (isa<TemplateTemplateParmDecl>(Pack)) {
2732 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2733 E->getPackLoc(), TU)))
2734 return true;
2735
2736 continue;
2737 }
2738
2739 // Non-type template parameter packs and function parameter packs are
2740 // treated like DeclRefExpr cursors.
2741 continue;
2742 }
2743
2744 case VisitorJob::LambdaExprPartsKind: {
2745 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002746 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2748 CEnd = E->explicit_capture_end();
2749 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002750 // FIXME: Lambda init-captures.
2751 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002752 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002753
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2755 C->getLocation(),
2756 TU)))
2757 return true;
2758 }
2759
2760 // Visit parameters and return type, if present.
2761 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2762 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2763 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2764 // Visit the whole type.
2765 if (Visit(TL))
2766 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002767 } else if (FunctionProtoTypeLoc Proto =
2768 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002769 if (E->hasExplicitParameters()) {
2770 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002771 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2772 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 return true;
2774 } else {
2775 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002776 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 return true;
2778 }
2779 }
2780 }
2781 break;
2782 }
2783
2784 case VisitorJob::PostChildrenVisitKind:
2785 if (PostChildrenVisitor(Parent, ClientData))
2786 return true;
2787 break;
2788 }
2789 }
2790 return false;
2791}
2792
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002793bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002794 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002795 if (!WorkListFreeList.empty()) {
2796 WL = WorkListFreeList.back();
2797 WL->clear();
2798 WorkListFreeList.pop_back();
2799 }
2800 else {
2801 WL = new VisitorWorkList();
2802 WorkListCache.push_back(WL);
2803 }
2804 EnqueueWorkList(*WL, S);
2805 bool result = RunVisitorWorkList(*WL);
2806 WorkListFreeList.push_back(WL);
2807 return result;
2808}
2809
2810namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002811typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002812RefNamePieces
2813buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2814 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2815 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002816 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2817 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2818 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2819
2820 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2821
2822 RefNamePieces Pieces;
2823
2824 if (WantQualifier && QLoc.isValid())
2825 Pieces.push_back(QLoc);
2826
2827 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2828 Pieces.push_back(NI.getLoc());
2829
2830 if (WantTemplateArgs && TemplateArgs)
2831 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2832 TemplateArgs->RAngleLoc));
2833
2834 if (Kind == DeclarationName::CXXOperatorName) {
2835 Pieces.push_back(SourceLocation::getFromRawEncoding(
2836 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2837 Pieces.push_back(SourceLocation::getFromRawEncoding(
2838 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2839 }
2840
2841 if (WantSinglePiece) {
2842 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2843 Pieces.clear();
2844 Pieces.push_back(R);
2845 }
2846
2847 return Pieces;
2848}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002849}
Guy Benyei11169dd2012-12-18 14:30:41 +00002850
2851//===----------------------------------------------------------------------===//
2852// Misc. API hooks.
2853//===----------------------------------------------------------------------===//
2854
Chad Rosier05c71aa2013-03-27 18:28:23 +00002855static void fatal_error_handler(void *user_data, const std::string& reason,
2856 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 // Write the result out to stderr avoiding errs() because raw_ostreams can
2858 // call report_fatal_error.
2859 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2860 ::abort();
2861}
2862
Chandler Carruth66660742014-06-27 16:37:27 +00002863namespace {
2864struct RegisterFatalErrorHandler {
2865 RegisterFatalErrorHandler() {
2866 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2867 }
2868};
2869}
2870
2871static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2872
Guy Benyei11169dd2012-12-18 14:30:41 +00002873extern "C" {
2874CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2875 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 // We use crash recovery to make some of our APIs more reliable, implicitly
2877 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002878 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2879 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002880
Chandler Carruth66660742014-06-27 16:37:27 +00002881 // Look through the managed static to trigger construction of the managed
2882 // static which registers our fatal error handler. This ensures it is only
2883 // registered once.
2884 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002885
Adrian Prantlbc068582015-07-08 01:00:30 +00002886 // Initialize targets for clang module support.
2887 llvm::InitializeAllTargets();
2888 llvm::InitializeAllTargetMCs();
2889 llvm::InitializeAllAsmPrinters();
2890 llvm::InitializeAllAsmParsers();
2891
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002892 CIndexer *CIdxr = new CIndexer();
2893
Guy Benyei11169dd2012-12-18 14:30:41 +00002894 if (excludeDeclarationsFromPCH)
2895 CIdxr->setOnlyLocalDecls();
2896 if (displayDiagnostics)
2897 CIdxr->setDisplayDiagnostics();
2898
2899 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2900 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2901 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2902 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2903 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2904 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2905
2906 return CIdxr;
2907}
2908
2909void clang_disposeIndex(CXIndex CIdx) {
2910 if (CIdx)
2911 delete static_cast<CIndexer *>(CIdx);
2912}
2913
2914void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2915 if (CIdx)
2916 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2917}
2918
2919unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2920 if (CIdx)
2921 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2922 return 0;
2923}
2924
2925void clang_toggleCrashRecovery(unsigned isEnabled) {
2926 if (isEnabled)
2927 llvm::CrashRecoveryContext::Enable();
2928 else
2929 llvm::CrashRecoveryContext::Disable();
2930}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002931
Guy Benyei11169dd2012-12-18 14:30:41 +00002932CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2933 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002934 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935 enum CXErrorCode Result =
2936 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002937 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002938 assert((TU && Result == CXError_Success) ||
2939 (!TU && Result != CXError_Success));
2940 return TU;
2941}
2942
2943enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2944 const char *ast_filename,
2945 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002946 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002947 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002948
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002949 if (!CIdx || !ast_filename || !out_TU)
2950 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002951
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002952 LOG_FUNC_SECTION {
2953 *Log << ast_filename;
2954 }
2955
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2957 FileSystemOptions FileSystemOpts;
2958
Justin Bognerd512c1e2014-10-15 00:33:06 +00002959 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2960 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002961 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002962 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
2963 FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002964 /*CaptureDiagnostics=*/true,
2965 /*AllowPCHWithCompilerErrors=*/true,
2966 /*UserFilesAreVolatile=*/true);
2967 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002968 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002969}
2970
2971unsigned clang_defaultEditingTranslationUnitOptions() {
2972 return CXTranslationUnit_PrecompiledPreamble |
2973 CXTranslationUnit_CacheCompletionResults;
2974}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975
Guy Benyei11169dd2012-12-18 14:30:41 +00002976CXTranslationUnit
2977clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2978 const char *source_filename,
2979 int num_command_line_args,
2980 const char * const *command_line_args,
2981 unsigned num_unsaved_files,
2982 struct CXUnsavedFile *unsaved_files) {
2983 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2984 return clang_parseTranslationUnit(CIdx, source_filename,
2985 command_line_args, num_command_line_args,
2986 unsaved_files, num_unsaved_files,
2987 Options);
2988}
2989
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00002990static CXErrorCode
2991clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
2992 const char *const *command_line_args,
2993 int num_command_line_args,
2994 ArrayRef<CXUnsavedFile> unsaved_files,
2995 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002996 // Set up the initial return values.
2997 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002998 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002999
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003001 if (!CIdx || !out_TU)
3002 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003003
Guy Benyei11169dd2012-12-18 14:30:41 +00003004 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3005
3006 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3007 setThreadBackgroundPriority();
3008
3009 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3010 // FIXME: Add a flag for modules.
3011 TranslationUnitKind TUKind
3012 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003013 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 = options & CXTranslationUnit_CacheCompletionResults;
3015 bool IncludeBriefCommentsInCodeCompletion
3016 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3017 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3018 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3019
3020 // Configure the diagnostics.
3021 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003022 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003023
3024 // Recover resources if we crash before exiting this function.
3025 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3026 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003027 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003028
Ahmed Charlesb8984322014-03-07 20:03:18 +00003029 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3030 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003031
3032 // Recover resources if we crash before exiting this function.
3033 llvm::CrashRecoveryContextCleanupRegistrar<
3034 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3035
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003036 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003037 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003038 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003039 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 }
3041
Ahmed Charlesb8984322014-03-07 20:03:18 +00003042 std::unique_ptr<std::vector<const char *>> Args(
3043 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003044
3045 // Recover resources if we crash before exiting this method.
3046 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3047 ArgsCleanup(Args.get());
3048
3049 // Since the Clang C library is primarily used by batch tools dealing with
3050 // (often very broken) source code, where spell-checking can have a
3051 // significant negative impact on performance (particularly when
3052 // precompiled headers are involved), we disable it by default.
3053 // Only do this if we haven't found a spell-checking-related argument.
3054 bool FoundSpellCheckingArgument = false;
3055 for (int I = 0; I != num_command_line_args; ++I) {
3056 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3057 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3058 FoundSpellCheckingArgument = true;
3059 break;
3060 }
3061 }
3062 if (!FoundSpellCheckingArgument)
3063 Args->push_back("-fno-spell-checking");
3064
3065 Args->insert(Args->end(), command_line_args,
3066 command_line_args + num_command_line_args);
3067
3068 // The 'source_filename' argument is optional. If the caller does not
3069 // specify it then it is assumed that the source file is specified
3070 // in the actual argument list.
3071 // Put the source file after command_line_args otherwise if '-x' flag is
3072 // present it will be unused.
3073 if (source_filename)
3074 Args->push_back(source_filename);
3075
3076 // Do we need the detailed preprocessing record?
3077 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3078 Args->push_back("-Xclang");
3079 Args->push_back("-detailed-preprocessing-record");
3080 }
3081
3082 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003083 std::unique_ptr<ASTUnit> ErrUnit;
3084 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003085 Args->data(), Args->data() + Args->size(),
3086 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003087 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3088 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3089 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3090 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3091 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3092 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003093
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003094 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003095 if (!Unit && !ErrUnit)
3096 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003097
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 if (NumErrors != Diags->getClient()->getNumErrors()) {
3099 // Make sure to check that 'Unit' is non-NULL.
3100 if (CXXIdx->getDisplayDiagnostics())
3101 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3102 }
3103
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003104 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3105 return CXError_ASTReadError;
3106
3107 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3108 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003109}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003110
3111CXTranslationUnit
3112clang_parseTranslationUnit(CXIndex CIdx,
3113 const char *source_filename,
3114 const char *const *command_line_args,
3115 int num_command_line_args,
3116 struct CXUnsavedFile *unsaved_files,
3117 unsigned num_unsaved_files,
3118 unsigned options) {
3119 CXTranslationUnit TU;
3120 enum CXErrorCode Result = clang_parseTranslationUnit2(
3121 CIdx, source_filename, command_line_args, num_command_line_args,
3122 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003123 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003124 assert((TU && Result == CXError_Success) ||
3125 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003126 return TU;
3127}
3128
3129enum CXErrorCode clang_parseTranslationUnit2(
3130 CXIndex CIdx,
3131 const char *source_filename,
3132 const char *const *command_line_args,
3133 int num_command_line_args,
3134 struct CXUnsavedFile *unsaved_files,
3135 unsigned num_unsaved_files,
3136 unsigned options,
3137 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003138 LOG_FUNC_SECTION {
3139 *Log << source_filename << ": ";
3140 for (int i = 0; i != num_command_line_args; ++i)
3141 *Log << command_line_args[i] << " ";
3142 }
3143
Alp Toker9d85b182014-07-07 01:23:14 +00003144 if (num_unsaved_files && !unsaved_files)
3145 return CXError_InvalidArguments;
3146
Alp Toker5c532982014-07-07 22:42:03 +00003147 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003148 auto ParseTranslationUnitImpl = [=, &result] {
3149 result = clang_parseTranslationUnit_Impl(
3150 CIdx, source_filename, command_line_args, num_command_line_args,
3151 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3152 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 llvm::CrashRecoveryContext CRC;
3154
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003155 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3157 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3158 fprintf(stderr, " 'command_line_args' : [");
3159 for (int i = 0; i != num_command_line_args; ++i) {
3160 if (i)
3161 fprintf(stderr, ", ");
3162 fprintf(stderr, "'%s'", command_line_args[i]);
3163 }
3164 fprintf(stderr, "],\n");
3165 fprintf(stderr, " 'unsaved_files' : [");
3166 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3167 if (i)
3168 fprintf(stderr, ", ");
3169 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3170 unsaved_files[i].Length);
3171 }
3172 fprintf(stderr, "],\n");
3173 fprintf(stderr, " 'options' : %d,\n", options);
3174 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003175
3176 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003178 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003179 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 }
Alp Toker5c532982014-07-07 22:42:03 +00003181
3182 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183}
3184
3185unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3186 return CXSaveTranslationUnit_None;
3187}
3188
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003189static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3190 const char *FileName,
3191 unsigned options) {
3192 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3194 setThreadBackgroundPriority();
3195
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003196 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3197 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003198}
3199
3200int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3201 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003202 LOG_FUNC_SECTION {
3203 *Log << TU << ' ' << FileName;
3204 }
3205
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003206 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003207 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003209 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003210
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003211 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3213 if (!CXXUnit->hasSema())
3214 return CXSaveError_InvalidTU;
3215
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003216 CXSaveError result;
3217 auto SaveTranslationUnitImpl = [=, &result]() {
3218 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3219 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003220
3221 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3222 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003223 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003224
3225 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3226 PrintLibclangResourceUsage(TU);
3227
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003228 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 }
3230
3231 // We have an AST that has invalid nodes due to compiler errors.
3232 // Use a crash recovery thread for protection.
3233
3234 llvm::CrashRecoveryContext CRC;
3235
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003236 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3238 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3239 fprintf(stderr, " 'options' : %d,\n", options);
3240 fprintf(stderr, "}\n");
3241
3242 return CXSaveError_Unknown;
3243
3244 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3245 PrintLibclangResourceUsage(TU);
3246 }
3247
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003248 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003249}
3250
3251void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3252 if (CTUnit) {
3253 // If the translation unit has been marked as unsafe to free, just discard
3254 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003255 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3256 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 return;
3258
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003259 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003260 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3262 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003263 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 delete CTUnit;
3265 }
3266}
3267
3268unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3269 return CXReparse_None;
3270}
3271
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003272static CXErrorCode
3273clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3274 ArrayRef<CXUnsavedFile> unsaved_files,
3275 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003276 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003277 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003278 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003279 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003280 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
3282 // Reset the associated diagnostics.
3283 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003284 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003286 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3288 setThreadBackgroundPriority();
3289
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003290 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003292
3293 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3294 new std::vector<ASTUnit::RemappedFile>());
3295
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 // Recover resources if we crash before exiting this function.
3297 llvm::CrashRecoveryContextCleanupRegistrar<
3298 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003299
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003300 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003301 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003302 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003303 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003305
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003306 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3307 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003308 return CXError_Success;
3309 if (isASTReadError(CXXUnit))
3310 return CXError_ASTReadError;
3311 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003312}
3313
3314int clang_reparseTranslationUnit(CXTranslationUnit TU,
3315 unsigned num_unsaved_files,
3316 struct CXUnsavedFile *unsaved_files,
3317 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003318 LOG_FUNC_SECTION {
3319 *Log << TU;
3320 }
3321
Alp Toker9d85b182014-07-07 01:23:14 +00003322 if (num_unsaved_files && !unsaved_files)
3323 return CXError_InvalidArguments;
3324
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003325 CXErrorCode result;
3326 auto ReparseTranslationUnitImpl = [=, &result]() {
3327 result = clang_reparseTranslationUnit_Impl(
3328 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3329 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003330
3331 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003332 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003333 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335
3336 llvm::CrashRecoveryContext CRC;
3337
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003338 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003340 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003341 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3343 PrintLibclangResourceUsage(TU);
3344
Alp Toker5c532982014-07-07 22:42:03 +00003345 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346}
3347
3348
3349CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003350 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003351 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003352 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003353 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003355 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357}
3358
3359CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003360 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003361 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003362 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003363 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003364
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003365 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3367}
3368
3369} // end: extern "C"
3370
3371//===----------------------------------------------------------------------===//
3372// CXFile Operations.
3373//===----------------------------------------------------------------------===//
3374
3375extern "C" {
3376CXString clang_getFileName(CXFile SFile) {
3377 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003378 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003379
3380 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003381 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003382}
3383
3384time_t clang_getFileTime(CXFile SFile) {
3385 if (!SFile)
3386 return 0;
3387
3388 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3389 return FEnt->getModificationTime();
3390}
3391
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003392CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003393 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003394 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003395 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003396 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003397
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003398 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003399
3400 FileManager &FMgr = CXXUnit->getFileManager();
3401 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3402}
3403
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003404unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3405 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003406 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003407 LOG_BAD_TU(TU);
3408 return 0;
3409 }
3410
3411 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 return 0;
3413
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003414 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 FileEntry *FEnt = static_cast<FileEntry *>(file);
3416 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3417 .isFileMultipleIncludeGuarded(FEnt);
3418}
3419
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003420int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3421 if (!file || !outID)
3422 return 1;
3423
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003424 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003425 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3426 outID->data[0] = ID.getDevice();
3427 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003428 outID->data[2] = FEnt->getModificationTime();
3429 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003430}
3431
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003432int clang_File_isEqual(CXFile file1, CXFile file2) {
3433 if (file1 == file2)
3434 return true;
3435
3436 if (!file1 || !file2)
3437 return false;
3438
3439 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3440 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3441 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3442}
3443
Guy Benyei11169dd2012-12-18 14:30:41 +00003444} // end: extern "C"
3445
3446//===----------------------------------------------------------------------===//
3447// CXCursor Operations.
3448//===----------------------------------------------------------------------===//
3449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003450static const Decl *getDeclFromExpr(const Stmt *E) {
3451 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 return getDeclFromExpr(CE->getSubExpr());
3453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003454 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003456 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003460 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 if (PRE->isExplicitProperty())
3462 return PRE->getExplicitProperty();
3463 // It could be messaging both getter and setter as in:
3464 // ++myobj.myprop;
3465 // in which case prefer to associate the setter since it is less obvious
3466 // from inspecting the source that the setter is going to get called.
3467 if (PRE->isMessagingSetter())
3468 return PRE->getImplicitPropertySetter();
3469 return PRE->getImplicitPropertyGetter();
3470 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 if (Expr *Src = OVE->getSourceExpr())
3475 return getDeclFromExpr(Src);
3476
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 if (!CE->isElidable())
3481 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 return OME->getMethodDecl();
3484
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003487 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3489 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3492 isa<ParmVarDecl>(SizeOfPack->getPack()))
3493 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003494
3495 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003496}
3497
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003498static SourceLocation getLocationFromExpr(const Expr *E) {
3499 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 return getLocationFromExpr(CE->getSubExpr());
3501
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003502 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003504 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003506 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003508 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003510 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003512 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 return PropRef->getLocation();
3514
3515 return E->getLocStart();
3516}
3517
3518extern "C" {
3519
3520unsigned clang_visitChildren(CXCursor parent,
3521 CXCursorVisitor visitor,
3522 CXClientData client_data) {
3523 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3524 /*VisitPreprocessorLast=*/false);
3525 return CursorVis.VisitChildren(parent);
3526}
3527
3528#ifndef __has_feature
3529#define __has_feature(x) 0
3530#endif
3531#if __has_feature(blocks)
3532typedef enum CXChildVisitResult
3533 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3534
3535static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3536 CXClientData client_data) {
3537 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3538 return block(cursor, parent);
3539}
3540#else
3541// If we are compiled with a compiler that doesn't have native blocks support,
3542// define and call the block manually, so the
3543typedef struct _CXChildVisitResult
3544{
3545 void *isa;
3546 int flags;
3547 int reserved;
3548 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3549 CXCursor);
3550} *CXCursorVisitorBlock;
3551
3552static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3553 CXClientData client_data) {
3554 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3555 return block->invoke(block, cursor, parent);
3556}
3557#endif
3558
3559
3560unsigned clang_visitChildrenWithBlock(CXCursor parent,
3561 CXCursorVisitorBlock block) {
3562 return clang_visitChildren(parent, visitWithBlock, block);
3563}
3564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003567 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003569 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003571 if (const ObjCPropertyImplDecl *PropImpl =
3572 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003574 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003576 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003578 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003580 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 }
3582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003583 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003584 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003585
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003586 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3588 // and returns different names. NamedDecl returns the class name and
3589 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003591
3592 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003593 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003594
3595 SmallString<1024> S;
3596 llvm::raw_svector_ostream os(S);
3597 ND->printName(os);
3598
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600}
3601
3602CXString clang_getCursorSpelling(CXCursor C) {
3603 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003604 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
3606 if (clang_isReference(C.kind)) {
3607 switch (C.kind) {
3608 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003609 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003613 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003617 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 }
3621 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003622 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003626 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 assert(Type && "Missing type decl");
3628
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003629 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 getAsString());
3631 }
3632 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 assert(Template && "Missing template decl");
3635
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003636 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 }
3638
3639 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003640 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 assert(NS && "Missing namespace decl");
3642
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003643 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 }
3645
3646 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003647 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 assert(Field && "Missing member decl");
3649
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 }
3652
3653 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003654 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 assert(Label && "Missing label");
3656
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659
3660 case CXCursor_OverloadedDeclRef: {
3661 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3663 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003664 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003665 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003667 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003668 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 OverloadedTemplateStorage *Ovl
3670 = Storage.get<OverloadedTemplateStorage*>();
3671 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003672 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003673 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
3676 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003677 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 assert(Var && "Missing variable decl");
3679
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003680 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 }
3682
3683 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686 }
3687
3688 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003689 const Expr *E = getCursorExpr(C);
3690
3691 if (C.kind == CXCursor_ObjCStringLiteral ||
3692 C.kind == CXCursor_StringLiteral) {
3693 const StringLiteral *SLit;
3694 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3695 SLit = OSL->getString();
3696 } else {
3697 SLit = cast<StringLiteral>(E);
3698 }
3699 SmallString<256> Buf;
3700 llvm::raw_svector_ostream OS(Buf);
3701 SLit->outputString(OS);
3702 return cxstring::createDup(OS.str());
3703 }
3704
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003705 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 if (D)
3707 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003708 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 }
3710
3711 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003712 const Stmt *S = getCursorStmt(C);
3713 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003715
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003716 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 }
3718
3719 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 ->getNameStart());
3722
3723 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 ->getNameStart());
3726
3727 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003728 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003729
3730 if (clang_isDeclaration(C.kind))
3731 return getDeclSpelling(getCursorDecl(C));
3732
3733 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003734 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003735 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 }
3737
3738 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003739 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003740 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 }
3742
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003743 if (C.kind == CXCursor_PackedAttr) {
3744 return cxstring::createRef("packed");
3745 }
3746
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003747 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003748}
3749
3750CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3751 unsigned pieceIndex,
3752 unsigned options) {
3753 if (clang_Cursor_isNull(C))
3754 return clang_getNullRange();
3755
3756 ASTContext &Ctx = getCursorContext(C);
3757
3758 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003759 const Stmt *S = getCursorStmt(C);
3760 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 if (pieceIndex > 0)
3762 return clang_getNullRange();
3763 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3764 }
3765
3766 return clang_getNullRange();
3767 }
3768
3769 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003770 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3772 if (pieceIndex >= ME->getNumSelectorLocs())
3773 return clang_getNullRange();
3774 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3775 }
3776 }
3777
3778 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3779 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003780 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3782 if (pieceIndex >= MD->getNumSelectorLocs())
3783 return clang_getNullRange();
3784 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3785 }
3786 }
3787
3788 if (C.kind == CXCursor_ObjCCategoryDecl ||
3789 C.kind == CXCursor_ObjCCategoryImplDecl) {
3790 if (pieceIndex > 0)
3791 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003792 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3794 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003795 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3797 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3798 }
3799
3800 if (C.kind == CXCursor_ModuleImportDecl) {
3801 if (pieceIndex > 0)
3802 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003803 if (const ImportDecl *ImportD =
3804 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3806 if (!Locs.empty())
3807 return cxloc::translateSourceRange(Ctx,
3808 SourceRange(Locs.front(), Locs.back()));
3809 }
3810 return clang_getNullRange();
3811 }
3812
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003813 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3814 C.kind == CXCursor_ConversionFunction) {
3815 if (pieceIndex > 0)
3816 return clang_getNullRange();
3817 if (const FunctionDecl *FD =
3818 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3819 DeclarationNameInfo FunctionName = FD->getNameInfo();
3820 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3821 }
3822 return clang_getNullRange();
3823 }
3824
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 // FIXME: A CXCursor_InclusionDirective should give the location of the
3826 // filename, but we don't keep track of this.
3827
3828 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3829 // but we don't keep track of this.
3830
3831 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3832 // but we don't keep track of this.
3833
3834 // Default handling, give the location of the cursor.
3835
3836 if (pieceIndex > 0)
3837 return clang_getNullRange();
3838
3839 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3840 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3841 return cxloc::translateSourceRange(Ctx, Loc);
3842}
3843
Eli Bendersky44a206f2014-07-31 18:04:56 +00003844CXString clang_Cursor_getMangling(CXCursor C) {
3845 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3846 return cxstring::createEmpty();
3847
Eli Bendersky44a206f2014-07-31 18:04:56 +00003848 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003849 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003850 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3851 return cxstring::createEmpty();
3852
Eli Bendersky79759592014-08-01 15:01:10 +00003853 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003854 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003855 ASTContext &Ctx = ND->getASTContext();
3856 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003857
Eli Bendersky79759592014-08-01 15:01:10 +00003858 std::string FrontendBuf;
3859 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3860 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003861
Eli Bendersky79759592014-08-01 15:01:10 +00003862 // Now apply backend mangling.
3863 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003864 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003865
3866 std::string FinalBuf;
3867 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003868 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3869 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003870
3871 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003872}
3873
Guy Benyei11169dd2012-12-18 14:30:41 +00003874CXString clang_getCursorDisplayName(CXCursor C) {
3875 if (!clang_isDeclaration(C.kind))
3876 return clang_getCursorSpelling(C);
3877
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003878 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003880 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003881
3882 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003883 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 D = FunTmpl->getTemplatedDecl();
3885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 SmallString<64> Str;
3888 llvm::raw_svector_ostream OS(Str);
3889 OS << *Function;
3890 if (Function->getPrimaryTemplate())
3891 OS << "<>";
3892 OS << "(";
3893 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3894 if (I)
3895 OS << ", ";
3896 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3897 }
3898
3899 if (Function->isVariadic()) {
3900 if (Function->getNumParams())
3901 OS << ", ";
3902 OS << "...";
3903 }
3904 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003905 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 }
3907
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003908 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 SmallString<64> Str;
3910 llvm::raw_svector_ostream OS(Str);
3911 OS << *ClassTemplate;
3912 OS << "<";
3913 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3914 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3915 if (I)
3916 OS << ", ";
3917
3918 NamedDecl *Param = Params->getParam(I);
3919 if (Param->getIdentifier()) {
3920 OS << Param->getIdentifier()->getName();
3921 continue;
3922 }
3923
3924 // There is no parameter name, which makes this tricky. Try to come up
3925 // with something useful that isn't too long.
3926 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3927 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3928 else if (NonTypeTemplateParmDecl *NTTP
3929 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3930 OS << NTTP->getType().getAsString(Policy);
3931 else
3932 OS << "template<...> class";
3933 }
3934
3935 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003936 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 }
3938
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3941 // If the type was explicitly written, use that.
3942 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003943 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003944
Benjamin Kramer9170e912013-02-22 15:46:01 +00003945 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 llvm::raw_svector_ostream OS(Str);
3947 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003948 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 ClassSpec->getTemplateArgs().data(),
3950 ClassSpec->getTemplateArgs().size(),
3951 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003952 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 }
3954
3955 return clang_getCursorSpelling(C);
3956}
3957
3958CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3959 switch (Kind) {
3960 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004088 case CXCursor_ObjCSelfExpr:
4089 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004178 case CXCursor_SEHLeaveStmt:
4179 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004208 case CXCursor_PackedAttr:
4209 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004210 case CXCursor_PureAttr:
4211 return cxstring::createRef("attribute(pure)");
4212 case CXCursor_ConstAttr:
4213 return cxstring::createRef("attribute(const)");
4214 case CXCursor_NoDuplicateAttr:
4215 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004216 case CXCursor_CUDAConstantAttr:
4217 return cxstring::createRef("attribute(constant)");
4218 case CXCursor_CUDADeviceAttr:
4219 return cxstring::createRef("attribute(device)");
4220 case CXCursor_CUDAGlobalAttr:
4221 return cxstring::createRef("attribute(global)");
4222 case CXCursor_CUDAHostAttr:
4223 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004224 case CXCursor_CUDASharedAttr:
4225 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004274 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004275 return cxstring::createRef("OMPParallelDirective");
4276 case CXCursor_OMPSimdDirective:
4277 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004278 case CXCursor_OMPForDirective:
4279 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004280 case CXCursor_OMPForSimdDirective:
4281 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004282 case CXCursor_OMPSectionsDirective:
4283 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004284 case CXCursor_OMPSectionDirective:
4285 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004286 case CXCursor_OMPSingleDirective:
4287 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004288 case CXCursor_OMPMasterDirective:
4289 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004290 case CXCursor_OMPCriticalDirective:
4291 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004292 case CXCursor_OMPParallelForDirective:
4293 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004294 case CXCursor_OMPParallelForSimdDirective:
4295 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004296 case CXCursor_OMPParallelSectionsDirective:
4297 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004298 case CXCursor_OMPTaskDirective:
4299 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004300 case CXCursor_OMPTaskyieldDirective:
4301 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004302 case CXCursor_OMPBarrierDirective:
4303 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004304 case CXCursor_OMPTaskwaitDirective:
4305 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004306 case CXCursor_OMPTaskgroupDirective:
4307 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004308 case CXCursor_OMPFlushDirective:
4309 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004310 case CXCursor_OMPOrderedDirective:
4311 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004312 case CXCursor_OMPAtomicDirective:
4313 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004314 case CXCursor_OMPTargetDirective:
4315 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004316 case CXCursor_OMPTargetDataDirective:
4317 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004318 case CXCursor_OMPTeamsDirective:
4319 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004320 case CXCursor_OMPCancellationPointDirective:
4321 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004322 case CXCursor_OMPCancelDirective:
4323 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004324 case CXCursor_OverloadCandidate:
4325 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 }
4327
4328 llvm_unreachable("Unhandled CXCursorKind");
4329}
4330
4331struct GetCursorData {
4332 SourceLocation TokenBeginLoc;
4333 bool PointsAtMacroArgExpansion;
4334 bool VisitedObjCPropertyImplDecl;
4335 SourceLocation VisitedDeclaratorDeclStartLoc;
4336 CXCursor &BestCursor;
4337
4338 GetCursorData(SourceManager &SM,
4339 SourceLocation tokenBegin, CXCursor &outputCursor)
4340 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4341 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4342 VisitedObjCPropertyImplDecl = false;
4343 }
4344};
4345
4346static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4347 CXCursor parent,
4348 CXClientData client_data) {
4349 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4350 CXCursor *BestCursor = &Data->BestCursor;
4351
4352 // If we point inside a macro argument we should provide info of what the
4353 // token is so use the actual cursor, don't replace it with a macro expansion
4354 // cursor.
4355 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4356 return CXChildVisit_Recurse;
4357
4358 if (clang_isDeclaration(cursor.kind)) {
4359 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004360 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4362 if (MD->isImplicit())
4363 return CXChildVisit_Break;
4364
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004365 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4367 // Check that when we have multiple @class references in the same line,
4368 // that later ones do not override the previous ones.
4369 // If we have:
4370 // @class Foo, Bar;
4371 // source ranges for both start at '@', so 'Bar' will end up overriding
4372 // 'Foo' even though the cursor location was at 'Foo'.
4373 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4374 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4377 if (PrevID != ID &&
4378 !PrevID->isThisDeclarationADefinition() &&
4379 !ID->isThisDeclarationADefinition())
4380 return CXChildVisit_Break;
4381 }
4382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004383 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4385 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4386 // Check that when we have multiple declarators in the same line,
4387 // that later ones do not override the previous ones.
4388 // If we have:
4389 // int Foo, Bar;
4390 // source ranges for both start at 'int', so 'Bar' will end up overriding
4391 // 'Foo' even though the cursor location was at 'Foo'.
4392 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4393 return CXChildVisit_Break;
4394 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4395
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004396 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4398 (void)PropImp;
4399 // Check that when we have multiple @synthesize in the same line,
4400 // that later ones do not override the previous ones.
4401 // If we have:
4402 // @synthesize Foo, Bar;
4403 // source ranges for both start at '@', so 'Bar' will end up overriding
4404 // 'Foo' even though the cursor location was at 'Foo'.
4405 if (Data->VisitedObjCPropertyImplDecl)
4406 return CXChildVisit_Break;
4407 Data->VisitedObjCPropertyImplDecl = true;
4408 }
4409 }
4410
4411 if (clang_isExpression(cursor.kind) &&
4412 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 // Avoid having the cursor of an expression replace the declaration cursor
4415 // when the expression source range overlaps the declaration range.
4416 // This can happen for C++ constructor expressions whose range generally
4417 // include the variable declaration, e.g.:
4418 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4419 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4420 D->getLocation() == Data->TokenBeginLoc)
4421 return CXChildVisit_Break;
4422 }
4423 }
4424
4425 // If our current best cursor is the construction of a temporary object,
4426 // don't replace that cursor with a type reference, because we want
4427 // clang_getCursor() to point at the constructor.
4428 if (clang_isExpression(BestCursor->kind) &&
4429 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4430 cursor.kind == CXCursor_TypeRef) {
4431 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4432 // as having the actual point on the type reference.
4433 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4434 return CXChildVisit_Recurse;
4435 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004436
4437 // If we already have an Objective-C superclass reference, don't
4438 // update it further.
4439 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4440 return CXChildVisit_Break;
4441
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 *BestCursor = cursor;
4443 return CXChildVisit_Recurse;
4444}
4445
4446CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004447 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004448 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004449 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004450 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004451
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004452 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4454
4455 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4456 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4457
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004458 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 CXFile SearchFile;
4460 unsigned SearchLine, SearchColumn;
4461 CXFile ResultFile;
4462 unsigned ResultLine, ResultColumn;
4463 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4464 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4465 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004466
4467 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4468 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004469 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004470 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 SearchFileName = clang_getFileName(SearchFile);
4472 ResultFileName = clang_getFileName(ResultFile);
4473 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4474 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004475 *Log << llvm::format("(%s:%d:%d) = %s",
4476 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4477 clang_getCString(KindSpelling))
4478 << llvm::format("(%s:%d:%d):%s%s",
4479 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4480 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 clang_disposeString(SearchFileName);
4482 clang_disposeString(ResultFileName);
4483 clang_disposeString(KindSpelling);
4484 clang_disposeString(USR);
4485
4486 CXCursor Definition = clang_getCursorDefinition(Result);
4487 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4488 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4489 CXString DefinitionKindSpelling
4490 = clang_getCursorKindSpelling(Definition.kind);
4491 CXFile DefinitionFile;
4492 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004493 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004494 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004496 *Log << llvm::format(" -> %s(%s:%d:%d)",
4497 clang_getCString(DefinitionKindSpelling),
4498 clang_getCString(DefinitionFileName),
4499 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 clang_disposeString(DefinitionFileName);
4501 clang_disposeString(DefinitionKindSpelling);
4502 }
4503 }
4504
4505 return Result;
4506}
4507
4508CXCursor clang_getNullCursor(void) {
4509 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4510}
4511
4512unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004513 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4514 // can't set consistently. For example, when visiting a DeclStmt we will set
4515 // it but we don't set it on the result of clang_getCursorDefinition for
4516 // a reference of the same declaration.
4517 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4518 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4519 // to provide that kind of info.
4520 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004521 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004522 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004523 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004524
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 return X == Y;
4526}
4527
4528unsigned clang_hashCursor(CXCursor C) {
4529 unsigned Index = 0;
4530 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4531 Index = 1;
4532
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004533 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 std::make_pair(C.kind, C.data[Index]));
4535}
4536
4537unsigned clang_isInvalid(enum CXCursorKind K) {
4538 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4539}
4540
4541unsigned clang_isDeclaration(enum CXCursorKind K) {
4542 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4543 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4544}
4545
4546unsigned clang_isReference(enum CXCursorKind K) {
4547 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4548}
4549
4550unsigned clang_isExpression(enum CXCursorKind K) {
4551 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4552}
4553
4554unsigned clang_isStatement(enum CXCursorKind K) {
4555 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4556}
4557
4558unsigned clang_isAttribute(enum CXCursorKind K) {
4559 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4560}
4561
4562unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4563 return K == CXCursor_TranslationUnit;
4564}
4565
4566unsigned clang_isPreprocessing(enum CXCursorKind K) {
4567 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4568}
4569
4570unsigned clang_isUnexposed(enum CXCursorKind K) {
4571 switch (K) {
4572 case CXCursor_UnexposedDecl:
4573 case CXCursor_UnexposedExpr:
4574 case CXCursor_UnexposedStmt:
4575 case CXCursor_UnexposedAttr:
4576 return true;
4577 default:
4578 return false;
4579 }
4580}
4581
4582CXCursorKind clang_getCursorKind(CXCursor C) {
4583 return C.kind;
4584}
4585
4586CXSourceLocation clang_getCursorLocation(CXCursor C) {
4587 if (clang_isReference(C.kind)) {
4588 switch (C.kind) {
4589 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004590 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 = getCursorObjCSuperClassRef(C);
4592 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4593 }
4594
4595 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004596 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 = getCursorObjCProtocolRef(C);
4598 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4599 }
4600
4601 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004602 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 = getCursorObjCClassRef(C);
4604 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4605 }
4606
4607 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004608 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4610 }
4611
4612 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 std::pair<const TemplateDecl *, SourceLocation> P =
4614 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4616 }
4617
4618 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004619 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4621 }
4622
4623 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4626 }
4627
4628 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004629 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4631 }
4632
4633 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004634 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 if (!BaseSpec)
4636 return clang_getNullLocation();
4637
4638 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4639 return cxloc::translateSourceLocation(getCursorContext(C),
4640 TSInfo->getTypeLoc().getBeginLoc());
4641
4642 return cxloc::translateSourceLocation(getCursorContext(C),
4643 BaseSpec->getLocStart());
4644 }
4645
4646 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004647 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4649 }
4650
4651 case CXCursor_OverloadedDeclRef:
4652 return cxloc::translateSourceLocation(getCursorContext(C),
4653 getCursorOverloadedDeclRef(C).second);
4654
4655 default:
4656 // FIXME: Need a way to enumerate all non-reference cases.
4657 llvm_unreachable("Missed a reference kind");
4658 }
4659 }
4660
4661 if (clang_isExpression(C.kind))
4662 return cxloc::translateSourceLocation(getCursorContext(C),
4663 getLocationFromExpr(getCursorExpr(C)));
4664
4665 if (clang_isStatement(C.kind))
4666 return cxloc::translateSourceLocation(getCursorContext(C),
4667 getCursorStmt(C)->getLocStart());
4668
4669 if (C.kind == CXCursor_PreprocessingDirective) {
4670 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4671 return cxloc::translateSourceLocation(getCursorContext(C), L);
4672 }
4673
4674 if (C.kind == CXCursor_MacroExpansion) {
4675 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004676 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 return cxloc::translateSourceLocation(getCursorContext(C), L);
4678 }
4679
4680 if (C.kind == CXCursor_MacroDefinition) {
4681 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4682 return cxloc::translateSourceLocation(getCursorContext(C), L);
4683 }
4684
4685 if (C.kind == CXCursor_InclusionDirective) {
4686 SourceLocation L
4687 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4688 return cxloc::translateSourceLocation(getCursorContext(C), L);
4689 }
4690
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004691 if (clang_isAttribute(C.kind)) {
4692 SourceLocation L
4693 = cxcursor::getCursorAttr(C)->getLocation();
4694 return cxloc::translateSourceLocation(getCursorContext(C), L);
4695 }
4696
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 if (!clang_isDeclaration(C.kind))
4698 return clang_getNullLocation();
4699
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004700 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 if (!D)
4702 return clang_getNullLocation();
4703
4704 SourceLocation Loc = D->getLocation();
4705 // FIXME: Multiple variables declared in a single declaration
4706 // currently lack the information needed to correctly determine their
4707 // ranges when accounting for the type-specifier. We use context
4708 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4709 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004710 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 if (!cxcursor::isFirstInDeclGroup(C))
4712 Loc = VD->getLocation();
4713 }
4714
4715 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004716 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 Loc = MD->getSelectorStartLoc();
4718
4719 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4720}
4721
4722} // end extern "C"
4723
4724CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4725 assert(TU);
4726
4727 // Guard against an invalid SourceLocation, or we may assert in one
4728 // of the following calls.
4729 if (SLoc.isInvalid())
4730 return clang_getNullCursor();
4731
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004732 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004733
4734 // Translate the given source location to make it point at the beginning of
4735 // the token under the cursor.
4736 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4737 CXXUnit->getASTContext().getLangOpts());
4738
4739 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4740 if (SLoc.isValid()) {
4741 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4742 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4743 /*VisitPreprocessorLast=*/true,
4744 /*VisitIncludedEntities=*/false,
4745 SourceLocation(SLoc));
4746 CursorVis.visitFileRegion();
4747 }
4748
4749 return Result;
4750}
4751
4752static SourceRange getRawCursorExtent(CXCursor C) {
4753 if (clang_isReference(C.kind)) {
4754 switch (C.kind) {
4755 case CXCursor_ObjCSuperClassRef:
4756 return getCursorObjCSuperClassRef(C).second;
4757
4758 case CXCursor_ObjCProtocolRef:
4759 return getCursorObjCProtocolRef(C).second;
4760
4761 case CXCursor_ObjCClassRef:
4762 return getCursorObjCClassRef(C).second;
4763
4764 case CXCursor_TypeRef:
4765 return getCursorTypeRef(C).second;
4766
4767 case CXCursor_TemplateRef:
4768 return getCursorTemplateRef(C).second;
4769
4770 case CXCursor_NamespaceRef:
4771 return getCursorNamespaceRef(C).second;
4772
4773 case CXCursor_MemberRef:
4774 return getCursorMemberRef(C).second;
4775
4776 case CXCursor_CXXBaseSpecifier:
4777 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4778
4779 case CXCursor_LabelRef:
4780 return getCursorLabelRef(C).second;
4781
4782 case CXCursor_OverloadedDeclRef:
4783 return getCursorOverloadedDeclRef(C).second;
4784
4785 case CXCursor_VariableRef:
4786 return getCursorVariableRef(C).second;
4787
4788 default:
4789 // FIXME: Need a way to enumerate all non-reference cases.
4790 llvm_unreachable("Missed a reference kind");
4791 }
4792 }
4793
4794 if (clang_isExpression(C.kind))
4795 return getCursorExpr(C)->getSourceRange();
4796
4797 if (clang_isStatement(C.kind))
4798 return getCursorStmt(C)->getSourceRange();
4799
4800 if (clang_isAttribute(C.kind))
4801 return getCursorAttr(C)->getRange();
4802
4803 if (C.kind == CXCursor_PreprocessingDirective)
4804 return cxcursor::getCursorPreprocessingDirective(C);
4805
4806 if (C.kind == CXCursor_MacroExpansion) {
4807 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004808 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 return TU->mapRangeFromPreamble(Range);
4810 }
4811
4812 if (C.kind == CXCursor_MacroDefinition) {
4813 ASTUnit *TU = getCursorASTUnit(C);
4814 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4815 return TU->mapRangeFromPreamble(Range);
4816 }
4817
4818 if (C.kind == CXCursor_InclusionDirective) {
4819 ASTUnit *TU = getCursorASTUnit(C);
4820 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4821 return TU->mapRangeFromPreamble(Range);
4822 }
4823
4824 if (C.kind == CXCursor_TranslationUnit) {
4825 ASTUnit *TU = getCursorASTUnit(C);
4826 FileID MainID = TU->getSourceManager().getMainFileID();
4827 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4828 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4829 return SourceRange(Start, End);
4830 }
4831
4832 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 if (!D)
4835 return SourceRange();
4836
4837 SourceRange R = D->getSourceRange();
4838 // FIXME: Multiple variables declared in a single declaration
4839 // currently lack the information needed to correctly determine their
4840 // ranges when accounting for the type-specifier. We use context
4841 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4842 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 if (!cxcursor::isFirstInDeclGroup(C))
4845 R.setBegin(VD->getLocation());
4846 }
4847 return R;
4848 }
4849 return SourceRange();
4850}
4851
4852/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4853/// the decl-specifier-seq for declarations.
4854static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4855 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 if (!D)
4858 return SourceRange();
4859
4860 SourceRange R = D->getSourceRange();
4861
4862 // Adjust the start of the location for declarations preceded by
4863 // declaration specifiers.
4864 SourceLocation StartLoc;
4865 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4866 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4867 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4870 StartLoc = TI->getTypeLoc().getLocStart();
4871 }
4872
4873 if (StartLoc.isValid() && R.getBegin().isValid() &&
4874 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4875 R.setBegin(StartLoc);
4876
4877 // FIXME: Multiple variables declared in a single declaration
4878 // currently lack the information needed to correctly determine their
4879 // ranges when accounting for the type-specifier. We use context
4880 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4881 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 if (!cxcursor::isFirstInDeclGroup(C))
4884 R.setBegin(VD->getLocation());
4885 }
4886
4887 return R;
4888 }
4889
4890 return getRawCursorExtent(C);
4891}
4892
4893extern "C" {
4894
4895CXSourceRange clang_getCursorExtent(CXCursor C) {
4896 SourceRange R = getRawCursorExtent(C);
4897 if (R.isInvalid())
4898 return clang_getNullRange();
4899
4900 return cxloc::translateSourceRange(getCursorContext(C), R);
4901}
4902
4903CXCursor clang_getCursorReferenced(CXCursor C) {
4904 if (clang_isInvalid(C.kind))
4905 return clang_getNullCursor();
4906
4907 CXTranslationUnit tu = getCursorTU(C);
4908 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 if (!D)
4911 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 if (const ObjCPropertyImplDecl *PropImpl =
4915 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4917 return MakeCXCursor(Property, tu);
4918
4919 return C;
4920 }
4921
4922 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004923 const Expr *E = getCursorExpr(C);
4924 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 if (D) {
4926 CXCursor declCursor = MakeCXCursor(D, tu);
4927 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4928 declCursor);
4929 return declCursor;
4930 }
4931
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004932 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004933 return MakeCursorOverloadedDeclRef(Ovl, tu);
4934
4935 return clang_getNullCursor();
4936 }
4937
4938 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004939 const Stmt *S = getCursorStmt(C);
4940 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 if (LabelDecl *label = Goto->getLabel())
4942 if (LabelStmt *labelS = label->getStmt())
4943 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4944
4945 return clang_getNullCursor();
4946 }
Richard Smith66a81862015-05-04 02:25:31 +00004947
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004949 if (const MacroDefinitionRecord *Def =
4950 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004951 return MakeMacroDefinitionCursor(Def, tu);
4952 }
4953
4954 if (!clang_isReference(C.kind))
4955 return clang_getNullCursor();
4956
4957 switch (C.kind) {
4958 case CXCursor_ObjCSuperClassRef:
4959 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4960
4961 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004962 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4963 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 return MakeCXCursor(Def, tu);
4965
4966 return MakeCXCursor(Prot, tu);
4967 }
4968
4969 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004970 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4971 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 return MakeCXCursor(Def, tu);
4973
4974 return MakeCXCursor(Class, tu);
4975 }
4976
4977 case CXCursor_TypeRef:
4978 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4979
4980 case CXCursor_TemplateRef:
4981 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4982
4983 case CXCursor_NamespaceRef:
4984 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4985
4986 case CXCursor_MemberRef:
4987 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4988
4989 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004990 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4992 tu ));
4993 }
4994
4995 case CXCursor_LabelRef:
4996 // FIXME: We end up faking the "parent" declaration here because we
4997 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004998 return MakeCXCursor(getCursorLabelRef(C).first,
4999 cxtu::getASTUnit(tu)->getASTContext()
5000 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 tu);
5002
5003 case CXCursor_OverloadedDeclRef:
5004 return C;
5005
5006 case CXCursor_VariableRef:
5007 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5008
5009 default:
5010 // We would prefer to enumerate all non-reference cursor kinds here.
5011 llvm_unreachable("Unhandled reference cursor kind");
5012 }
5013}
5014
5015CXCursor clang_getCursorDefinition(CXCursor C) {
5016 if (clang_isInvalid(C.kind))
5017 return clang_getNullCursor();
5018
5019 CXTranslationUnit TU = getCursorTU(C);
5020
5021 bool WasReference = false;
5022 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5023 C = clang_getCursorReferenced(C);
5024 WasReference = true;
5025 }
5026
5027 if (C.kind == CXCursor_MacroExpansion)
5028 return clang_getCursorReferenced(C);
5029
5030 if (!clang_isDeclaration(C.kind))
5031 return clang_getNullCursor();
5032
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005033 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 if (!D)
5035 return clang_getNullCursor();
5036
5037 switch (D->getKind()) {
5038 // Declaration kinds that don't really separate the notions of
5039 // declaration and definition.
5040 case Decl::Namespace:
5041 case Decl::Typedef:
5042 case Decl::TypeAlias:
5043 case Decl::TypeAliasTemplate:
5044 case Decl::TemplateTypeParm:
5045 case Decl::EnumConstant:
5046 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005047 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 case Decl::IndirectField:
5049 case Decl::ObjCIvar:
5050 case Decl::ObjCAtDefsField:
5051 case Decl::ImplicitParam:
5052 case Decl::ParmVar:
5053 case Decl::NonTypeTemplateParm:
5054 case Decl::TemplateTemplateParm:
5055 case Decl::ObjCCategoryImpl:
5056 case Decl::ObjCImplementation:
5057 case Decl::AccessSpec:
5058 case Decl::LinkageSpec:
5059 case Decl::ObjCPropertyImpl:
5060 case Decl::FileScopeAsm:
5061 case Decl::StaticAssert:
5062 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005063 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 case Decl::Label: // FIXME: Is this right??
5065 case Decl::ClassScopeFunctionSpecialization:
5066 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005067 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005068 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return C;
5070
5071 // Declaration kinds that don't make any sense here, but are
5072 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005073 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005075 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 break;
5077
5078 // Declaration kinds for which the definition is not resolvable.
5079 case Decl::UnresolvedUsingTypename:
5080 case Decl::UnresolvedUsingValue:
5081 break;
5082
5083 case Decl::UsingDirective:
5084 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5085 TU);
5086
5087 case Decl::NamespaceAlias:
5088 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5089
5090 case Decl::Enum:
5091 case Decl::Record:
5092 case Decl::CXXRecord:
5093 case Decl::ClassTemplateSpecialization:
5094 case Decl::ClassTemplatePartialSpecialization:
5095 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5096 return MakeCXCursor(Def, TU);
5097 return clang_getNullCursor();
5098
5099 case Decl::Function:
5100 case Decl::CXXMethod:
5101 case Decl::CXXConstructor:
5102 case Decl::CXXDestructor:
5103 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005104 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005106 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 return clang_getNullCursor();
5108 }
5109
Larisse Voufo39a1e502013-08-06 01:03:05 +00005110 case Decl::Var:
5111 case Decl::VarTemplateSpecialization:
5112 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005114 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 return MakeCXCursor(Def, TU);
5116 return clang_getNullCursor();
5117 }
5118
5119 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005120 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5122 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5123 return clang_getNullCursor();
5124 }
5125
5126 case Decl::ClassTemplate: {
5127 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5128 ->getDefinition())
5129 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5130 TU);
5131 return clang_getNullCursor();
5132 }
5133
Larisse Voufo39a1e502013-08-06 01:03:05 +00005134 case Decl::VarTemplate: {
5135 if (VarDecl *Def =
5136 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5137 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5138 return clang_getNullCursor();
5139 }
5140
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 case Decl::Using:
5142 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5143 D->getLocation(), TU);
5144
5145 case Decl::UsingShadow:
5146 return clang_getCursorDefinition(
5147 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5148 TU));
5149
5150 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005151 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 if (Method->isThisDeclarationADefinition())
5153 return C;
5154
5155 // Dig out the method definition in the associated
5156 // @implementation, if we have it.
5157 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005158 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5160 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5161 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5162 Method->isInstanceMethod()))
5163 if (Def->isThisDeclarationADefinition())
5164 return MakeCXCursor(Def, TU);
5165
5166 return clang_getNullCursor();
5167 }
5168
5169 case Decl::ObjCCategory:
5170 if (ObjCCategoryImplDecl *Impl
5171 = cast<ObjCCategoryDecl>(D)->getImplementation())
5172 return MakeCXCursor(Impl, TU);
5173 return clang_getNullCursor();
5174
5175 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005176 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 return MakeCXCursor(Def, TU);
5178 return clang_getNullCursor();
5179
5180 case Decl::ObjCInterface: {
5181 // There are two notions of a "definition" for an Objective-C
5182 // class: the interface and its implementation. When we resolved a
5183 // reference to an Objective-C class, produce the @interface as
5184 // the definition; when we were provided with the interface,
5185 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005186 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005188 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 return MakeCXCursor(Def, TU);
5190 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5191 return MakeCXCursor(Impl, TU);
5192 return clang_getNullCursor();
5193 }
5194
5195 case Decl::ObjCProperty:
5196 // FIXME: We don't really know where to find the
5197 // ObjCPropertyImplDecls that implement this property.
5198 return clang_getNullCursor();
5199
5200 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005201 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005203 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 return MakeCXCursor(Def, TU);
5205
5206 return clang_getNullCursor();
5207
5208 case Decl::Friend:
5209 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5210 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5211 return clang_getNullCursor();
5212
5213 case Decl::FriendTemplate:
5214 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5215 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5216 return clang_getNullCursor();
5217 }
5218
5219 return clang_getNullCursor();
5220}
5221
5222unsigned clang_isCursorDefinition(CXCursor C) {
5223 if (!clang_isDeclaration(C.kind))
5224 return 0;
5225
5226 return clang_getCursorDefinition(C) == C;
5227}
5228
5229CXCursor clang_getCanonicalCursor(CXCursor C) {
5230 if (!clang_isDeclaration(C.kind))
5231 return C;
5232
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005233 if (const Decl *D = getCursorDecl(C)) {
5234 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5236 return MakeCXCursor(CatD, getCursorTU(C));
5237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005238 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5239 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 return MakeCXCursor(IFD, getCursorTU(C));
5241
5242 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5243 }
5244
5245 return C;
5246}
5247
5248int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5249 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5250}
5251
5252unsigned clang_getNumOverloadedDecls(CXCursor C) {
5253 if (C.kind != CXCursor_OverloadedDeclRef)
5254 return 0;
5255
5256 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005257 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 return E->getNumDecls();
5259
5260 if (OverloadedTemplateStorage *S
5261 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5262 return S->size();
5263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005264 const Decl *D = Storage.get<const Decl *>();
5265 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 return Using->shadow_size();
5267
5268 return 0;
5269}
5270
5271CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5272 if (cursor.kind != CXCursor_OverloadedDeclRef)
5273 return clang_getNullCursor();
5274
5275 if (index >= clang_getNumOverloadedDecls(cursor))
5276 return clang_getNullCursor();
5277
5278 CXTranslationUnit TU = getCursorTU(cursor);
5279 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005280 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 return MakeCXCursor(E->decls_begin()[index], TU);
5282
5283 if (OverloadedTemplateStorage *S
5284 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5285 return MakeCXCursor(S->begin()[index], TU);
5286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005287 const Decl *D = Storage.get<const Decl *>();
5288 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 // FIXME: This is, unfortunately, linear time.
5290 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5291 std::advance(Pos, index);
5292 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5293 }
5294
5295 return clang_getNullCursor();
5296}
5297
5298void clang_getDefinitionSpellingAndExtent(CXCursor C,
5299 const char **startBuf,
5300 const char **endBuf,
5301 unsigned *startLine,
5302 unsigned *startColumn,
5303 unsigned *endLine,
5304 unsigned *endColumn) {
5305 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005306 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5308
5309 SourceManager &SM = FD->getASTContext().getSourceManager();
5310 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5311 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5312 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5313 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5314 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5315 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5316}
5317
5318
5319CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5320 unsigned PieceIndex) {
5321 RefNamePieces Pieces;
5322
5323 switch (C.kind) {
5324 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005325 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5327 E->getQualifierLoc().getSourceRange());
5328 break;
5329
5330 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005331 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5333 E->getQualifierLoc().getSourceRange(),
5334 E->getOptionalExplicitTemplateArgs());
5335 break;
5336
5337 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005338 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005340 const Expr *Callee = OCE->getCallee();
5341 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 Callee = ICE->getSubExpr();
5343
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005344 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5346 DRE->getQualifierLoc().getSourceRange());
5347 }
5348 break;
5349
5350 default:
5351 break;
5352 }
5353
5354 if (Pieces.empty()) {
5355 if (PieceIndex == 0)
5356 return clang_getCursorExtent(C);
5357 } else if (PieceIndex < Pieces.size()) {
5358 SourceRange R = Pieces[PieceIndex];
5359 if (R.isValid())
5360 return cxloc::translateSourceRange(getCursorContext(C), R);
5361 }
5362
5363 return clang_getNullRange();
5364}
5365
5366void clang_enableStackTraces(void) {
5367 llvm::sys::PrintStackTraceOnErrorSignal();
5368}
5369
5370void clang_executeOnThread(void (*fn)(void*), void *user_data,
5371 unsigned stack_size) {
5372 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5373}
5374
5375} // end: extern "C"
5376
5377//===----------------------------------------------------------------------===//
5378// Token-based Operations.
5379//===----------------------------------------------------------------------===//
5380
5381/* CXToken layout:
5382 * int_data[0]: a CXTokenKind
5383 * int_data[1]: starting token location
5384 * int_data[2]: token length
5385 * int_data[3]: reserved
5386 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5387 * otherwise unused.
5388 */
5389extern "C" {
5390
5391CXTokenKind clang_getTokenKind(CXToken CXTok) {
5392 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5393}
5394
5395CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5396 switch (clang_getTokenKind(CXTok)) {
5397 case CXToken_Identifier:
5398 case CXToken_Keyword:
5399 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005400 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 ->getNameStart());
5402
5403 case CXToken_Literal: {
5404 // We have stashed the starting pointer in the ptr_data field. Use it.
5405 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005406 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 }
5408
5409 case CXToken_Punctuation:
5410 case CXToken_Comment:
5411 break;
5412 }
5413
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005414 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005415 LOG_BAD_TU(TU);
5416 return cxstring::createEmpty();
5417 }
5418
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 // We have to find the starting buffer pointer the hard way, by
5420 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005421 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005423 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005424
5425 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5426 std::pair<FileID, unsigned> LocInfo
5427 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5428 bool Invalid = false;
5429 StringRef Buffer
5430 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5431 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005432 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005433
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005434 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005435}
5436
5437CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005438 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005439 LOG_BAD_TU(TU);
5440 return clang_getNullLocation();
5441 }
5442
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005443 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 if (!CXXUnit)
5445 return clang_getNullLocation();
5446
5447 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5448 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5449}
5450
5451CXSourceRange clang_getTokenExtent(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_getNullRange();
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_getNullRange();
5460
5461 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5462 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5463}
5464
5465static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5466 SmallVectorImpl<CXToken> &CXTokens) {
5467 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5468 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005469 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005471 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005472
5473 // Cannot tokenize across files.
5474 if (BeginLocInfo.first != EndLocInfo.first)
5475 return;
5476
5477 // Create a lexer
5478 bool Invalid = false;
5479 StringRef Buffer
5480 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5481 if (Invalid)
5482 return;
5483
5484 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5485 CXXUnit->getASTContext().getLangOpts(),
5486 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5487 Lex.SetCommentRetentionState(true);
5488
5489 // Lex tokens until we hit the end of the range.
5490 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5491 Token Tok;
5492 bool previousWasAt = false;
5493 do {
5494 // Lex the next token
5495 Lex.LexFromRawLexer(Tok);
5496 if (Tok.is(tok::eof))
5497 break;
5498
5499 // Initialize the CXToken.
5500 CXToken CXTok;
5501
5502 // - Common fields
5503 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5504 CXTok.int_data[2] = Tok.getLength();
5505 CXTok.int_data[3] = 0;
5506
5507 // - Kind-specific fields
5508 if (Tok.isLiteral()) {
5509 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005510 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 } else if (Tok.is(tok::raw_identifier)) {
5512 // Lookup the identifier to determine whether we have a keyword.
5513 IdentifierInfo *II
5514 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5515
5516 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5517 CXTok.int_data[0] = CXToken_Keyword;
5518 }
5519 else {
5520 CXTok.int_data[0] = Tok.is(tok::identifier)
5521 ? CXToken_Identifier
5522 : CXToken_Keyword;
5523 }
5524 CXTok.ptr_data = II;
5525 } else if (Tok.is(tok::comment)) {
5526 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005527 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 } else {
5529 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005530 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 }
5532 CXTokens.push_back(CXTok);
5533 previousWasAt = Tok.is(tok::at);
5534 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5535}
5536
5537void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5538 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005539 LOG_FUNC_SECTION {
5540 *Log << TU << ' ' << Range;
5541 }
5542
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005544 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 if (NumTokens)
5546 *NumTokens = 0;
5547
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005548 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005549 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005550 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005551 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005552
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005553 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 if (!CXXUnit || !Tokens || !NumTokens)
5555 return;
5556
5557 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5558
5559 SourceRange R = cxloc::translateCXSourceRange(Range);
5560 if (R.isInvalid())
5561 return;
5562
5563 SmallVector<CXToken, 32> CXTokens;
5564 getTokens(CXXUnit, R, CXTokens);
5565
5566 if (CXTokens.empty())
5567 return;
5568
5569 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5570 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5571 *NumTokens = CXTokens.size();
5572}
5573
5574void clang_disposeTokens(CXTranslationUnit TU,
5575 CXToken *Tokens, unsigned NumTokens) {
5576 free(Tokens);
5577}
5578
5579} // end: extern "C"
5580
5581//===----------------------------------------------------------------------===//
5582// Token annotation APIs.
5583//===----------------------------------------------------------------------===//
5584
Guy Benyei11169dd2012-12-18 14:30:41 +00005585static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5586 CXCursor parent,
5587 CXClientData client_data);
5588static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5589 CXClientData client_data);
5590
5591namespace {
5592class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 CXToken *Tokens;
5594 CXCursor *Cursors;
5595 unsigned NumTokens;
5596 unsigned TokIdx;
5597 unsigned PreprocessingTokIdx;
5598 CursorVisitor AnnotateVis;
5599 SourceManager &SrcMgr;
5600 bool HasContextSensitiveKeywords;
5601
5602 struct PostChildrenInfo {
5603 CXCursor Cursor;
5604 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005605 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005606 unsigned BeforeChildrenTokenIdx;
5607 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005608 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005609
5610 CXToken &getTok(unsigned Idx) {
5611 assert(Idx < NumTokens);
5612 return Tokens[Idx];
5613 }
5614 const CXToken &getTok(unsigned Idx) const {
5615 assert(Idx < NumTokens);
5616 return Tokens[Idx];
5617 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 bool MoreTokens() const { return TokIdx < NumTokens; }
5619 unsigned NextToken() const { return TokIdx; }
5620 void AdvanceToken() { ++TokIdx; }
5621 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005622 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 }
5624 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005625 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 }
5627 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005628 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 }
5630
5631 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005632 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 SourceRange);
5634
5635public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005636 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005637 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005638 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005640 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 AnnotateTokensVisitor, this,
5642 /*VisitPreprocessorLast=*/true,
5643 /*VisitIncludedEntities=*/false,
5644 RegionOfInterest,
5645 /*VisitDeclsOnly=*/false,
5646 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005647 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 HasContextSensitiveKeywords(false) { }
5649
5650 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5651 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5652 bool postVisitChildren(CXCursor cursor);
5653 void AnnotateTokens();
5654
5655 /// \brief Determine whether the annotator saw any cursors that have
5656 /// context-sensitive keywords.
5657 bool hasContextSensitiveKeywords() const {
5658 return HasContextSensitiveKeywords;
5659 }
5660
5661 ~AnnotateTokensWorker() {
5662 assert(PostChildrenInfos.empty());
5663 }
5664};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005665}
Guy Benyei11169dd2012-12-18 14:30:41 +00005666
5667void AnnotateTokensWorker::AnnotateTokens() {
5668 // Walk the AST within the region of interest, annotating tokens
5669 // along the way.
5670 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005671}
Guy Benyei11169dd2012-12-18 14:30:41 +00005672
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673static inline void updateCursorAnnotation(CXCursor &Cursor,
5674 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005675 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005677 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005678}
5679
5680/// \brief It annotates and advances tokens with a cursor until the comparison
5681//// between the cursor location and the source range is the same as
5682/// \arg compResult.
5683///
5684/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5685/// Pass RangeOverlap to annotate tokens inside a range.
5686void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5687 RangeComparisonResult compResult,
5688 SourceRange range) {
5689 while (MoreTokens()) {
5690 const unsigned I = NextToken();
5691 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005692 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5693 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005694
5695 SourceLocation TokLoc = GetTokenLoc(I);
5696 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005697 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 AdvanceToken();
5699 continue;
5700 }
5701 break;
5702 }
5703}
5704
5705/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005706/// \returns true if it advanced beyond all macro tokens, false otherwise.
5707bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 CXCursor updateC,
5709 RangeComparisonResult compResult,
5710 SourceRange range) {
5711 assert(MoreTokens());
5712 assert(isFunctionMacroToken(NextToken()) &&
5713 "Should be called only for macro arg tokens");
5714
5715 // This works differently than annotateAndAdvanceTokens; because expanded
5716 // macro arguments can have arbitrary translation-unit source order, we do not
5717 // advance the token index one by one until a token fails the range test.
5718 // We only advance once past all of the macro arg tokens if all of them
5719 // pass the range test. If one of them fails we keep the token index pointing
5720 // at the start of the macro arg tokens so that the failing token will be
5721 // annotated by a subsequent annotation try.
5722
5723 bool atLeastOneCompFail = false;
5724
5725 unsigned I = NextToken();
5726 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5727 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5728 if (TokLoc.isFileID())
5729 continue; // not macro arg token, it's parens or comma.
5730 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5731 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5732 Cursors[I] = updateC;
5733 } else
5734 atLeastOneCompFail = true;
5735 }
5736
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005737 if (atLeastOneCompFail)
5738 return false;
5739
5740 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5741 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005742}
5743
5744enum CXChildVisitResult
5745AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 SourceRange cursorRange = getRawCursorExtent(cursor);
5747 if (cursorRange.isInvalid())
5748 return CXChildVisit_Recurse;
5749
5750 if (!HasContextSensitiveKeywords) {
5751 // Objective-C properties can have context-sensitive keywords.
5752 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005753 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5755 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5756 }
5757 // Objective-C methods can have context-sensitive keywords.
5758 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5759 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5762 if (Method->getObjCDeclQualifier())
5763 HasContextSensitiveKeywords = true;
5764 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005765 for (const auto *P : Method->params()) {
5766 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 HasContextSensitiveKeywords = true;
5768 break;
5769 }
5770 }
5771 }
5772 }
5773 }
5774 // C++ methods can have context-sensitive keywords.
5775 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005776 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005777 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5778 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5779 HasContextSensitiveKeywords = true;
5780 }
5781 }
5782 // C++ classes can have context-sensitive keywords.
5783 else if (cursor.kind == CXCursor_StructDecl ||
5784 cursor.kind == CXCursor_ClassDecl ||
5785 cursor.kind == CXCursor_ClassTemplate ||
5786 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005787 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 if (D->hasAttr<FinalAttr>())
5789 HasContextSensitiveKeywords = true;
5790 }
5791 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005792
5793 // Don't override a property annotation with its getter/setter method.
5794 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5795 parent.kind == CXCursor_ObjCPropertyDecl)
5796 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005797
5798 if (clang_isPreprocessing(cursor.kind)) {
5799 // Items in the preprocessing record are kept separate from items in
5800 // declarations, so we keep a separate token index.
5801 unsigned SavedTokIdx = TokIdx;
5802 TokIdx = PreprocessingTokIdx;
5803
5804 // Skip tokens up until we catch up to the beginning of the preprocessing
5805 // entry.
5806 while (MoreTokens()) {
5807 const unsigned I = NextToken();
5808 SourceLocation TokLoc = GetTokenLoc(I);
5809 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5810 case RangeBefore:
5811 AdvanceToken();
5812 continue;
5813 case RangeAfter:
5814 case RangeOverlap:
5815 break;
5816 }
5817 break;
5818 }
5819
5820 // Look at all of the tokens within this range.
5821 while (MoreTokens()) {
5822 const unsigned I = NextToken();
5823 SourceLocation TokLoc = GetTokenLoc(I);
5824 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5825 case RangeBefore:
5826 llvm_unreachable("Infeasible");
5827 case RangeAfter:
5828 break;
5829 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005830 // For macro expansions, just note where the beginning of the macro
5831 // expansion occurs.
5832 if (cursor.kind == CXCursor_MacroExpansion) {
5833 if (TokLoc == cursorRange.getBegin())
5834 Cursors[I] = cursor;
5835 AdvanceToken();
5836 break;
5837 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005838 // We may have already annotated macro names inside macro definitions.
5839 if (Cursors[I].kind != CXCursor_MacroExpansion)
5840 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005841 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 continue;
5843 }
5844 break;
5845 }
5846
5847 // Save the preprocessing token index; restore the non-preprocessing
5848 // token index.
5849 PreprocessingTokIdx = TokIdx;
5850 TokIdx = SavedTokIdx;
5851 return CXChildVisit_Recurse;
5852 }
5853
5854 if (cursorRange.isInvalid())
5855 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005856
5857 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 const enum CXCursorKind K = clang_getCursorKind(parent);
5860 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005861 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5862 // Attributes are annotated out-of-order, skip tokens until we reach it.
5863 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005864 ? clang_getNullCursor() : parent;
5865
5866 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5867
5868 // Avoid having the cursor of an expression "overwrite" the annotation of the
5869 // variable declaration that it belongs to.
5870 // This can happen for C++ constructor expressions whose range generally
5871 // include the variable declaration, e.g.:
5872 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005873 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005874 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005875 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 const unsigned I = NextToken();
5877 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5878 E->getLocStart() == D->getLocation() &&
5879 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005880 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 AdvanceToken();
5882 }
5883 }
5884 }
5885
5886 // Before recursing into the children keep some state that we are going
5887 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5888 // extra work after the child nodes are visited.
5889 // Note that we don't call VisitChildren here to avoid traversing statements
5890 // code-recursively which can blow the stack.
5891
5892 PostChildrenInfo Info;
5893 Info.Cursor = cursor;
5894 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005895 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 Info.BeforeChildrenTokenIdx = NextToken();
5897 PostChildrenInfos.push_back(Info);
5898
5899 return CXChildVisit_Recurse;
5900}
5901
5902bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5903 if (PostChildrenInfos.empty())
5904 return false;
5905 const PostChildrenInfo &Info = PostChildrenInfos.back();
5906 if (!clang_equalCursors(Info.Cursor, cursor))
5907 return false;
5908
5909 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5910 const unsigned AfterChildren = NextToken();
5911 SourceRange cursorRange = Info.CursorRange;
5912
5913 // Scan the tokens that are at the end of the cursor, but are not captured
5914 // but the child cursors.
5915 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5916
5917 // Scan the tokens that are at the beginning of the cursor, but are not
5918 // capture by the child cursors.
5919 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5920 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5921 break;
5922
5923 Cursors[I] = cursor;
5924 }
5925
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005926 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5927 // encountered the attribute cursor.
5928 if (clang_isAttribute(cursor.kind))
5929 TokIdx = Info.BeforeReachingCursorIdx;
5930
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 PostChildrenInfos.pop_back();
5932 return false;
5933}
5934
5935static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5936 CXCursor parent,
5937 CXClientData client_data) {
5938 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5939}
5940
5941static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5942 CXClientData client_data) {
5943 return static_cast<AnnotateTokensWorker*>(client_data)->
5944 postVisitChildren(cursor);
5945}
5946
5947namespace {
5948
5949/// \brief Uses the macro expansions in the preprocessing record to find
5950/// and mark tokens that are macro arguments. This info is used by the
5951/// AnnotateTokensWorker.
5952class MarkMacroArgTokensVisitor {
5953 SourceManager &SM;
5954 CXToken *Tokens;
5955 unsigned NumTokens;
5956 unsigned CurIdx;
5957
5958public:
5959 MarkMacroArgTokensVisitor(SourceManager &SM,
5960 CXToken *tokens, unsigned numTokens)
5961 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5962
5963 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5964 if (cursor.kind != CXCursor_MacroExpansion)
5965 return CXChildVisit_Continue;
5966
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005967 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 if (macroRange.getBegin() == macroRange.getEnd())
5969 return CXChildVisit_Continue; // it's not a function macro.
5970
5971 for (; CurIdx < NumTokens; ++CurIdx) {
5972 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5973 macroRange.getBegin()))
5974 break;
5975 }
5976
5977 if (CurIdx == NumTokens)
5978 return CXChildVisit_Break;
5979
5980 for (; CurIdx < NumTokens; ++CurIdx) {
5981 SourceLocation tokLoc = getTokenLoc(CurIdx);
5982 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5983 break;
5984
5985 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5986 }
5987
5988 if (CurIdx == NumTokens)
5989 return CXChildVisit_Break;
5990
5991 return CXChildVisit_Continue;
5992 }
5993
5994private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005995 CXToken &getTok(unsigned Idx) {
5996 assert(Idx < NumTokens);
5997 return Tokens[Idx];
5998 }
5999 const CXToken &getTok(unsigned Idx) const {
6000 assert(Idx < NumTokens);
6001 return Tokens[Idx];
6002 }
6003
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006005 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 }
6007
6008 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6009 // The third field is reserved and currently not used. Use it here
6010 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006011 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 }
6013};
6014
6015} // end anonymous namespace
6016
6017static CXChildVisitResult
6018MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6019 CXClientData client_data) {
6020 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6021 parent);
6022}
6023
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006024/// \brief Used by \c annotatePreprocessorTokens.
6025/// \returns true if lexing was finished, false otherwise.
6026static bool lexNext(Lexer &Lex, Token &Tok,
6027 unsigned &NextIdx, unsigned NumTokens) {
6028 if (NextIdx >= NumTokens)
6029 return true;
6030
6031 ++NextIdx;
6032 Lex.LexFromRawLexer(Tok);
6033 if (Tok.is(tok::eof))
6034 return true;
6035
6036 return false;
6037}
6038
Guy Benyei11169dd2012-12-18 14:30:41 +00006039static void annotatePreprocessorTokens(CXTranslationUnit TU,
6040 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006041 CXCursor *Cursors,
6042 CXToken *Tokens,
6043 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006045
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006046 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6048 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006049 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006051 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006052
6053 if (BeginLocInfo.first != EndLocInfo.first)
6054 return;
6055
6056 StringRef Buffer;
6057 bool Invalid = false;
6058 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6059 if (Buffer.empty() || Invalid)
6060 return;
6061
6062 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6063 CXXUnit->getASTContext().getLangOpts(),
6064 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6065 Buffer.end());
6066 Lex.SetCommentRetentionState(true);
6067
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006068 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 // Lex tokens in raw mode until we hit the end of the range, to avoid
6070 // entering #includes or expanding macros.
6071 while (true) {
6072 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006073 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6074 break;
6075 unsigned TokIdx = NextIdx-1;
6076 assert(Tok.getLocation() ==
6077 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006078
6079 reprocess:
6080 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006081 // We have found a preprocessing directive. Annotate the tokens
6082 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 //
6084 // FIXME: Some simple tests here could identify macro definitions and
6085 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006086
6087 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006088 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6089 break;
6090
Craig Topper69186e72014-06-08 08:38:04 +00006091 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006092 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006093 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6094 break;
6095
6096 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006097 IdentifierInfo &II =
6098 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006099 SourceLocation MappedTokLoc =
6100 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6101 MI = getMacroInfo(II, MappedTokLoc, TU);
6102 }
6103 }
6104
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006105 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006106 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006107 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6108 finished = true;
6109 break;
6110 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006111 // If we are in a macro definition, check if the token was ever a
6112 // macro name and annotate it if that's the case.
6113 if (MI) {
6114 SourceLocation SaveLoc = Tok.getLocation();
6115 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006116 MacroDefinitionRecord *MacroDef =
6117 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006118 Tok.setLocation(SaveLoc);
6119 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006120 Cursors[NextIdx - 1] =
6121 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006122 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006123 } while (!Tok.isAtStartOfLine());
6124
6125 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6126 assert(TokIdx <= LastIdx);
6127 SourceLocation EndLoc =
6128 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6129 CXCursor Cursor =
6130 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6131
6132 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006133 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006134
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006135 if (finished)
6136 break;
6137 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 }
6140}
6141
6142// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006143static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6144 CXToken *Tokens, unsigned NumTokens,
6145 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006146 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6148 setThreadBackgroundPriority();
6149
6150 // Determine the region of interest, which contains all of the tokens.
6151 SourceRange RegionOfInterest;
6152 RegionOfInterest.setBegin(
6153 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6154 RegionOfInterest.setEnd(
6155 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6156 Tokens[NumTokens-1])));
6157
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 // Relex the tokens within the source range to look for preprocessing
6159 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006160 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006161
6162 // If begin location points inside a macro argument, set it to the expansion
6163 // location so we can have the full context when annotating semantically.
6164 {
6165 SourceManager &SM = CXXUnit->getSourceManager();
6166 SourceLocation Loc =
6167 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6168 if (Loc.isMacroID())
6169 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6170 }
6171
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6173 // Search and mark tokens that are macro argument expansions.
6174 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6175 Tokens, NumTokens);
6176 CursorVisitor MacroArgMarker(TU,
6177 MarkMacroArgTokensVisitorDelegate, &Visitor,
6178 /*VisitPreprocessorLast=*/true,
6179 /*VisitIncludedEntities=*/false,
6180 RegionOfInterest);
6181 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6182 }
6183
6184 // Annotate all of the source locations in the region of interest that map to
6185 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006186 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006187
6188 // FIXME: We use a ridiculous stack size here because the data-recursion
6189 // algorithm uses a large stack frame than the non-data recursive version,
6190 // and AnnotationTokensWorker currently transforms the data-recursion
6191 // algorithm back into a traditional recursion by explicitly calling
6192 // VisitChildren(). We will need to remove this explicit recursive call.
6193 W.AnnotateTokens();
6194
6195 // If we ran into any entities that involve context-sensitive keywords,
6196 // take another pass through the tokens to mark them as such.
6197 if (W.hasContextSensitiveKeywords()) {
6198 for (unsigned I = 0; I != NumTokens; ++I) {
6199 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6200 continue;
6201
6202 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6203 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006204 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6206 if (Property->getPropertyAttributesAsWritten() != 0 &&
6207 llvm::StringSwitch<bool>(II->getName())
6208 .Case("readonly", true)
6209 .Case("assign", true)
6210 .Case("unsafe_unretained", true)
6211 .Case("readwrite", true)
6212 .Case("retain", true)
6213 .Case("copy", true)
6214 .Case("nonatomic", true)
6215 .Case("atomic", true)
6216 .Case("getter", true)
6217 .Case("setter", true)
6218 .Case("strong", true)
6219 .Case("weak", true)
6220 .Default(false))
6221 Tokens[I].int_data[0] = CXToken_Keyword;
6222 }
6223 continue;
6224 }
6225
6226 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6227 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6228 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6229 if (llvm::StringSwitch<bool>(II->getName())
6230 .Case("in", true)
6231 .Case("out", true)
6232 .Case("inout", true)
6233 .Case("oneway", true)
6234 .Case("bycopy", true)
6235 .Case("byref", true)
6236 .Default(false))
6237 Tokens[I].int_data[0] = CXToken_Keyword;
6238 continue;
6239 }
6240
6241 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6242 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6243 Tokens[I].int_data[0] = CXToken_Keyword;
6244 continue;
6245 }
6246 }
6247 }
6248}
6249
6250extern "C" {
6251
6252void clang_annotateTokens(CXTranslationUnit TU,
6253 CXToken *Tokens, unsigned NumTokens,
6254 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006255 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006256 LOG_BAD_TU(TU);
6257 return;
6258 }
6259 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006260 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006262 }
6263
6264 LOG_FUNC_SECTION {
6265 *Log << TU << ' ';
6266 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6267 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6268 *Log << clang_getRange(bloc, eloc);
6269 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006270
6271 // Any token we don't specifically annotate will have a NULL cursor.
6272 CXCursor C = clang_getNullCursor();
6273 for (unsigned I = 0; I != NumTokens; ++I)
6274 Cursors[I] = C;
6275
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006276 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006277 if (!CXXUnit)
6278 return;
6279
6280 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006281
6282 auto AnnotateTokensImpl = [=]() {
6283 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6284 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006285 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006286 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006287 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6288 }
6289}
6290
6291} // end: extern "C"
6292
6293//===----------------------------------------------------------------------===//
6294// Operations for querying linkage of a cursor.
6295//===----------------------------------------------------------------------===//
6296
6297extern "C" {
6298CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6299 if (!clang_isDeclaration(cursor.kind))
6300 return CXLinkage_Invalid;
6301
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006302 const Decl *D = cxcursor::getCursorDecl(cursor);
6303 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006304 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006305 case NoLinkage:
6306 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 case InternalLinkage: return CXLinkage_Internal;
6308 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6309 case ExternalLinkage: return CXLinkage_External;
6310 };
6311
6312 return CXLinkage_Invalid;
6313}
6314} // end: extern "C"
6315
6316//===----------------------------------------------------------------------===//
6317// Operations for querying language of a cursor.
6318//===----------------------------------------------------------------------===//
6319
6320static CXLanguageKind getDeclLanguage(const Decl *D) {
6321 if (!D)
6322 return CXLanguage_C;
6323
6324 switch (D->getKind()) {
6325 default:
6326 break;
6327 case Decl::ImplicitParam:
6328 case Decl::ObjCAtDefsField:
6329 case Decl::ObjCCategory:
6330 case Decl::ObjCCategoryImpl:
6331 case Decl::ObjCCompatibleAlias:
6332 case Decl::ObjCImplementation:
6333 case Decl::ObjCInterface:
6334 case Decl::ObjCIvar:
6335 case Decl::ObjCMethod:
6336 case Decl::ObjCProperty:
6337 case Decl::ObjCPropertyImpl:
6338 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006339 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006340 return CXLanguage_ObjC;
6341 case Decl::CXXConstructor:
6342 case Decl::CXXConversion:
6343 case Decl::CXXDestructor:
6344 case Decl::CXXMethod:
6345 case Decl::CXXRecord:
6346 case Decl::ClassTemplate:
6347 case Decl::ClassTemplatePartialSpecialization:
6348 case Decl::ClassTemplateSpecialization:
6349 case Decl::Friend:
6350 case Decl::FriendTemplate:
6351 case Decl::FunctionTemplate:
6352 case Decl::LinkageSpec:
6353 case Decl::Namespace:
6354 case Decl::NamespaceAlias:
6355 case Decl::NonTypeTemplateParm:
6356 case Decl::StaticAssert:
6357 case Decl::TemplateTemplateParm:
6358 case Decl::TemplateTypeParm:
6359 case Decl::UnresolvedUsingTypename:
6360 case Decl::UnresolvedUsingValue:
6361 case Decl::Using:
6362 case Decl::UsingDirective:
6363 case Decl::UsingShadow:
6364 return CXLanguage_CPlusPlus;
6365 }
6366
6367 return CXLanguage_C;
6368}
6369
6370extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006371
6372static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6373 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6374 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006375
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006376 switch (D->getAvailability()) {
6377 case AR_Available:
6378 case AR_NotYetIntroduced:
6379 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006380 return getCursorAvailabilityForDecl(
6381 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006382 return CXAvailability_Available;
6383
6384 case AR_Deprecated:
6385 return CXAvailability_Deprecated;
6386
6387 case AR_Unavailable:
6388 return CXAvailability_NotAvailable;
6389 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006390
6391 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006392}
6393
Guy Benyei11169dd2012-12-18 14:30:41 +00006394enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6395 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006396 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6397 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006398
6399 return CXAvailability_Available;
6400}
6401
6402static CXVersion convertVersion(VersionTuple In) {
6403 CXVersion Out = { -1, -1, -1 };
6404 if (In.empty())
6405 return Out;
6406
6407 Out.Major = In.getMajor();
6408
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006409 Optional<unsigned> Minor = In.getMinor();
6410 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 Out.Minor = *Minor;
6412 else
6413 return Out;
6414
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006415 Optional<unsigned> Subminor = In.getSubminor();
6416 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 Out.Subminor = *Subminor;
6418
6419 return Out;
6420}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006421
6422static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6423 int *always_deprecated,
6424 CXString *deprecated_message,
6425 int *always_unavailable,
6426 CXString *unavailable_message,
6427 CXPlatformAvailability *availability,
6428 int availability_size) {
6429 bool HadAvailAttr = false;
6430 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006431 for (auto A : D->attrs()) {
6432 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006433 HadAvailAttr = true;
6434 if (always_deprecated)
6435 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006436 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006437 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006438 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006439 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006440 continue;
6441 }
6442
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006443 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006444 HadAvailAttr = true;
6445 if (always_unavailable)
6446 *always_unavailable = 1;
6447 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006448 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006449 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6450 }
6451 continue;
6452 }
6453
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006454 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006455 HadAvailAttr = true;
6456 if (N < availability_size) {
6457 availability[N].Platform
6458 = cxstring::createDup(Avail->getPlatform()->getName());
6459 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6460 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6461 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6462 availability[N].Unavailable = Avail->getUnavailable();
6463 availability[N].Message = cxstring::createDup(Avail->getMessage());
6464 }
6465 ++N;
6466 }
6467 }
6468
6469 if (!HadAvailAttr)
6470 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6471 return getCursorPlatformAvailabilityForDecl(
6472 cast<Decl>(EnumConst->getDeclContext()),
6473 always_deprecated,
6474 deprecated_message,
6475 always_unavailable,
6476 unavailable_message,
6477 availability,
6478 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006479
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006480 return N;
6481}
6482
Guy Benyei11169dd2012-12-18 14:30:41 +00006483int clang_getCursorPlatformAvailability(CXCursor cursor,
6484 int *always_deprecated,
6485 CXString *deprecated_message,
6486 int *always_unavailable,
6487 CXString *unavailable_message,
6488 CXPlatformAvailability *availability,
6489 int availability_size) {
6490 if (always_deprecated)
6491 *always_deprecated = 0;
6492 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006493 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006494 if (always_unavailable)
6495 *always_unavailable = 0;
6496 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006497 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006498
Guy Benyei11169dd2012-12-18 14:30:41 +00006499 if (!clang_isDeclaration(cursor.kind))
6500 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006502 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 if (!D)
6504 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006505
6506 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6507 deprecated_message,
6508 always_unavailable,
6509 unavailable_message,
6510 availability,
6511 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006512}
6513
6514void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6515 clang_disposeString(availability->Platform);
6516 clang_disposeString(availability->Message);
6517}
6518
6519CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6520 if (clang_isDeclaration(cursor.kind))
6521 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6522
6523 return CXLanguage_Invalid;
6524}
6525
6526 /// \brief If the given cursor is the "templated" declaration
6527 /// descibing a class or function template, return the class or
6528 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006529static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006531 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006533 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006534 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6535 return FunTmpl;
6536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006537 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6539 return ClassTmpl;
6540
6541 return D;
6542}
6543
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006544
6545enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6546 StorageClass sc = SC_None;
6547 const Decl *D = getCursorDecl(C);
6548 if (D) {
6549 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6550 sc = FD->getStorageClass();
6551 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6552 sc = VD->getStorageClass();
6553 } else {
6554 return CX_SC_Invalid;
6555 }
6556 } else {
6557 return CX_SC_Invalid;
6558 }
6559 switch (sc) {
6560 case SC_None:
6561 return CX_SC_None;
6562 case SC_Extern:
6563 return CX_SC_Extern;
6564 case SC_Static:
6565 return CX_SC_Static;
6566 case SC_PrivateExtern:
6567 return CX_SC_PrivateExtern;
6568 case SC_OpenCLWorkGroupLocal:
6569 return CX_SC_OpenCLWorkGroupLocal;
6570 case SC_Auto:
6571 return CX_SC_Auto;
6572 case SC_Register:
6573 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006574 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006575 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006576}
6577
Guy Benyei11169dd2012-12-18 14:30:41 +00006578CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6579 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006580 if (const Decl *D = getCursorDecl(cursor)) {
6581 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006582 if (!DC)
6583 return clang_getNullCursor();
6584
6585 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6586 getCursorTU(cursor));
6587 }
6588 }
6589
6590 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006591 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006592 return MakeCXCursor(D, getCursorTU(cursor));
6593 }
6594
6595 return clang_getNullCursor();
6596}
6597
6598CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6599 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006600 if (const Decl *D = getCursorDecl(cursor)) {
6601 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006602 if (!DC)
6603 return clang_getNullCursor();
6604
6605 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6606 getCursorTU(cursor));
6607 }
6608 }
6609
6610 // FIXME: Note that we can't easily compute the lexical context of a
6611 // statement or expression, so we return nothing.
6612 return clang_getNullCursor();
6613}
6614
6615CXFile clang_getIncludedFile(CXCursor cursor) {
6616 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006617 return nullptr;
6618
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006619 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006620 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006621}
6622
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006623unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6624 if (C.kind != CXCursor_ObjCPropertyDecl)
6625 return CXObjCPropertyAttr_noattr;
6626
6627 unsigned Result = CXObjCPropertyAttr_noattr;
6628 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6629 ObjCPropertyDecl::PropertyAttributeKind Attr =
6630 PD->getPropertyAttributesAsWritten();
6631
6632#define SET_CXOBJCPROP_ATTR(A) \
6633 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6634 Result |= CXObjCPropertyAttr_##A
6635 SET_CXOBJCPROP_ATTR(readonly);
6636 SET_CXOBJCPROP_ATTR(getter);
6637 SET_CXOBJCPROP_ATTR(assign);
6638 SET_CXOBJCPROP_ATTR(readwrite);
6639 SET_CXOBJCPROP_ATTR(retain);
6640 SET_CXOBJCPROP_ATTR(copy);
6641 SET_CXOBJCPROP_ATTR(nonatomic);
6642 SET_CXOBJCPROP_ATTR(setter);
6643 SET_CXOBJCPROP_ATTR(atomic);
6644 SET_CXOBJCPROP_ATTR(weak);
6645 SET_CXOBJCPROP_ATTR(strong);
6646 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6647#undef SET_CXOBJCPROP_ATTR
6648
6649 return Result;
6650}
6651
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006652unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6653 if (!clang_isDeclaration(C.kind))
6654 return CXObjCDeclQualifier_None;
6655
6656 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6657 const Decl *D = getCursorDecl(C);
6658 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6659 QT = MD->getObjCDeclQualifier();
6660 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6661 QT = PD->getObjCDeclQualifier();
6662 if (QT == Decl::OBJC_TQ_None)
6663 return CXObjCDeclQualifier_None;
6664
6665 unsigned Result = CXObjCDeclQualifier_None;
6666 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6667 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6668 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6669 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6670 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6671 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6672
6673 return Result;
6674}
6675
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006676unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6677 if (!clang_isDeclaration(C.kind))
6678 return 0;
6679
6680 const Decl *D = getCursorDecl(C);
6681 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6682 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6683 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6684 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6685
6686 return 0;
6687}
6688
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006689unsigned clang_Cursor_isVariadic(CXCursor C) {
6690 if (!clang_isDeclaration(C.kind))
6691 return 0;
6692
6693 const Decl *D = getCursorDecl(C);
6694 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6695 return FD->isVariadic();
6696 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6697 return MD->isVariadic();
6698
6699 return 0;
6700}
6701
Guy Benyei11169dd2012-12-18 14:30:41 +00006702CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6703 if (!clang_isDeclaration(C.kind))
6704 return clang_getNullRange();
6705
6706 const Decl *D = getCursorDecl(C);
6707 ASTContext &Context = getCursorContext(C);
6708 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6709 if (!RC)
6710 return clang_getNullRange();
6711
6712 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6713}
6714
6715CXString clang_Cursor_getRawCommentText(CXCursor C) {
6716 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006717 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006718
6719 const Decl *D = getCursorDecl(C);
6720 ASTContext &Context = getCursorContext(C);
6721 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6722 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6723 StringRef();
6724
6725 // Don't duplicate the string because RawText points directly into source
6726 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006727 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006728}
6729
6730CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6731 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006732 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006733
6734 const Decl *D = getCursorDecl(C);
6735 const ASTContext &Context = getCursorContext(C);
6736 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6737
6738 if (RC) {
6739 StringRef BriefText = RC->getBriefText(Context);
6740
6741 // Don't duplicate the string because RawComment ensures that this memory
6742 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006743 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006744 }
6745
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006746 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006747}
6748
Guy Benyei11169dd2012-12-18 14:30:41 +00006749CXModule clang_Cursor_getModule(CXCursor C) {
6750 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006751 if (const ImportDecl *ImportD =
6752 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 return ImportD->getImportedModule();
6754 }
6755
Craig Topper69186e72014-06-08 08:38:04 +00006756 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006757}
6758
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006759CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6760 if (isNotUsableTU(TU)) {
6761 LOG_BAD_TU(TU);
6762 return nullptr;
6763 }
6764 if (!File)
6765 return nullptr;
6766 FileEntry *FE = static_cast<FileEntry *>(File);
6767
6768 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6769 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6770 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6771
Richard Smithfeb54b62014-10-23 02:01:19 +00006772 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006773}
6774
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006775CXFile clang_Module_getASTFile(CXModule CXMod) {
6776 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006777 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006778 Module *Mod = static_cast<Module*>(CXMod);
6779 return const_cast<FileEntry *>(Mod->getASTFile());
6780}
6781
Guy Benyei11169dd2012-12-18 14:30:41 +00006782CXModule clang_Module_getParent(CXModule CXMod) {
6783 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006784 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 Module *Mod = static_cast<Module*>(CXMod);
6786 return Mod->Parent;
6787}
6788
6789CXString clang_Module_getName(CXModule CXMod) {
6790 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006791 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006792 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006793 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006794}
6795
6796CXString clang_Module_getFullName(CXModule CXMod) {
6797 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006798 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006800 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006801}
6802
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006803int clang_Module_isSystem(CXModule CXMod) {
6804 if (!CXMod)
6805 return 0;
6806 Module *Mod = static_cast<Module*>(CXMod);
6807 return Mod->IsSystem;
6808}
6809
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006810unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6811 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006812 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006813 LOG_BAD_TU(TU);
6814 return 0;
6815 }
6816 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006817 return 0;
6818 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006819 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6820 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6821 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006822}
6823
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006824CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6825 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006826 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006827 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006828 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006829 }
6830 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006831 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006832 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006833 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006834
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006835 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6836 if (Index < TopHeaders.size())
6837 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006838
Craig Topper69186e72014-06-08 08:38:04 +00006839 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006840}
6841
6842} // end: extern "C"
6843
6844//===----------------------------------------------------------------------===//
6845// C++ AST instrospection.
6846//===----------------------------------------------------------------------===//
6847
6848extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006849unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6850 if (!clang_isDeclaration(C.kind))
6851 return 0;
6852
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006853 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006854 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006855 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006856 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6857}
6858
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006859unsigned clang_CXXMethod_isConst(CXCursor C) {
6860 if (!clang_isDeclaration(C.kind))
6861 return 0;
6862
6863 const Decl *D = cxcursor::getCursorDecl(C);
6864 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006865 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006866 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6867}
6868
Guy Benyei11169dd2012-12-18 14:30:41 +00006869unsigned clang_CXXMethod_isStatic(CXCursor C) {
6870 if (!clang_isDeclaration(C.kind))
6871 return 0;
6872
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006873 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006874 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006875 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006876 return (Method && Method->isStatic()) ? 1 : 0;
6877}
6878
6879unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6880 if (!clang_isDeclaration(C.kind))
6881 return 0;
6882
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006883 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006884 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006885 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006886 return (Method && Method->isVirtual()) ? 1 : 0;
6887}
6888} // end: extern "C"
6889
6890//===----------------------------------------------------------------------===//
6891// Attribute introspection.
6892//===----------------------------------------------------------------------===//
6893
6894extern "C" {
6895CXType clang_getIBOutletCollectionType(CXCursor C) {
6896 if (C.kind != CXCursor_IBOutletCollectionAttr)
6897 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6898
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006899 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6901
6902 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6903}
6904} // end: extern "C"
6905
6906//===----------------------------------------------------------------------===//
6907// Inspecting memory usage.
6908//===----------------------------------------------------------------------===//
6909
6910typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6911
6912static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6913 enum CXTUResourceUsageKind k,
6914 unsigned long amount) {
6915 CXTUResourceUsageEntry entry = { k, amount };
6916 entries.push_back(entry);
6917}
6918
6919extern "C" {
6920
6921const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6922 const char *str = "";
6923 switch (kind) {
6924 case CXTUResourceUsage_AST:
6925 str = "ASTContext: expressions, declarations, and types";
6926 break;
6927 case CXTUResourceUsage_Identifiers:
6928 str = "ASTContext: identifiers";
6929 break;
6930 case CXTUResourceUsage_Selectors:
6931 str = "ASTContext: selectors";
6932 break;
6933 case CXTUResourceUsage_GlobalCompletionResults:
6934 str = "Code completion: cached global results";
6935 break;
6936 case CXTUResourceUsage_SourceManagerContentCache:
6937 str = "SourceManager: content cache allocator";
6938 break;
6939 case CXTUResourceUsage_AST_SideTables:
6940 str = "ASTContext: side tables";
6941 break;
6942 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6943 str = "SourceManager: malloc'ed memory buffers";
6944 break;
6945 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6946 str = "SourceManager: mmap'ed memory buffers";
6947 break;
6948 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6949 str = "ExternalASTSource: malloc'ed memory buffers";
6950 break;
6951 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6952 str = "ExternalASTSource: mmap'ed memory buffers";
6953 break;
6954 case CXTUResourceUsage_Preprocessor:
6955 str = "Preprocessor: malloc'ed memory";
6956 break;
6957 case CXTUResourceUsage_PreprocessingRecord:
6958 str = "Preprocessor: PreprocessingRecord";
6959 break;
6960 case CXTUResourceUsage_SourceManager_DataStructures:
6961 str = "SourceManager: data structures and tables";
6962 break;
6963 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6964 str = "Preprocessor: header search tables";
6965 break;
6966 }
6967 return str;
6968}
6969
6970CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006971 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006972 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006973 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006974 return usage;
6975 }
6976
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006977 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006978 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006979 ASTContext &astContext = astUnit->getASTContext();
6980
6981 // How much memory is used by AST nodes and types?
6982 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6983 (unsigned long) astContext.getASTAllocatedMemory());
6984
6985 // How much memory is used by identifiers?
6986 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6987 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6988
6989 // How much memory is used for selectors?
6990 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6991 (unsigned long) astContext.Selectors.getTotalMemory());
6992
6993 // How much memory is used by ASTContext's side tables?
6994 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6995 (unsigned long) astContext.getSideTableAllocatedMemory());
6996
6997 // How much memory is used for caching global code completion results?
6998 unsigned long completionBytes = 0;
6999 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007000 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007001 completionBytes = completionAllocator->getTotalMemory();
7002 }
7003 createCXTUResourceUsageEntry(*entries,
7004 CXTUResourceUsage_GlobalCompletionResults,
7005 completionBytes);
7006
7007 // How much memory is being used by SourceManager's content cache?
7008 createCXTUResourceUsageEntry(*entries,
7009 CXTUResourceUsage_SourceManagerContentCache,
7010 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7011
7012 // How much memory is being used by the MemoryBuffer's in SourceManager?
7013 const SourceManager::MemoryBufferSizes &srcBufs =
7014 astUnit->getSourceManager().getMemoryBufferSizes();
7015
7016 createCXTUResourceUsageEntry(*entries,
7017 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7018 (unsigned long) srcBufs.malloc_bytes);
7019 createCXTUResourceUsageEntry(*entries,
7020 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7021 (unsigned long) srcBufs.mmap_bytes);
7022 createCXTUResourceUsageEntry(*entries,
7023 CXTUResourceUsage_SourceManager_DataStructures,
7024 (unsigned long) astContext.getSourceManager()
7025 .getDataStructureSizes());
7026
7027 // How much memory is being used by the ExternalASTSource?
7028 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7029 const ExternalASTSource::MemoryBufferSizes &sizes =
7030 esrc->getMemoryBufferSizes();
7031
7032 createCXTUResourceUsageEntry(*entries,
7033 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7034 (unsigned long) sizes.malloc_bytes);
7035 createCXTUResourceUsageEntry(*entries,
7036 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7037 (unsigned long) sizes.mmap_bytes);
7038 }
7039
7040 // How much memory is being used by the Preprocessor?
7041 Preprocessor &pp = astUnit->getPreprocessor();
7042 createCXTUResourceUsageEntry(*entries,
7043 CXTUResourceUsage_Preprocessor,
7044 pp.getTotalMemory());
7045
7046 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7047 createCXTUResourceUsageEntry(*entries,
7048 CXTUResourceUsage_PreprocessingRecord,
7049 pRec->getTotalMemory());
7050 }
7051
7052 createCXTUResourceUsageEntry(*entries,
7053 CXTUResourceUsage_Preprocessor_HeaderSearch,
7054 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007055
Guy Benyei11169dd2012-12-18 14:30:41 +00007056 CXTUResourceUsage usage = { (void*) entries.get(),
7057 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007058 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007059 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007060 return usage;
7061}
7062
7063void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7064 if (usage.data)
7065 delete (MemUsageEntries*) usage.data;
7066}
7067
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007068CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7069 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007070 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007071 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007072
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007073 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007074 LOG_BAD_TU(TU);
7075 return skipped;
7076 }
7077
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007078 if (!file)
7079 return skipped;
7080
7081 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7082 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7083 if (!ppRec)
7084 return skipped;
7085
7086 ASTContext &Ctx = astUnit->getASTContext();
7087 SourceManager &sm = Ctx.getSourceManager();
7088 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7089 FileID wantedFileID = sm.translateFile(fileEntry);
7090
7091 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7092 std::vector<SourceRange> wantedRanges;
7093 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7094 i != ei; ++i) {
7095 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7096 wantedRanges.push_back(*i);
7097 }
7098
7099 skipped->count = wantedRanges.size();
7100 skipped->ranges = new CXSourceRange[skipped->count];
7101 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7102 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7103
7104 return skipped;
7105}
7106
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007107void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7108 if (ranges) {
7109 delete[] ranges->ranges;
7110 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007111 }
7112}
7113
Guy Benyei11169dd2012-12-18 14:30:41 +00007114} // end extern "C"
7115
7116void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7117 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7118 for (unsigned I = 0; I != Usage.numEntries; ++I)
7119 fprintf(stderr, " %s: %lu\n",
7120 clang_getTUResourceUsageName(Usage.entries[I].kind),
7121 Usage.entries[I].amount);
7122
7123 clang_disposeCXTUResourceUsage(Usage);
7124}
7125
7126//===----------------------------------------------------------------------===//
7127// Misc. utility functions.
7128//===----------------------------------------------------------------------===//
7129
7130/// Default to using an 8 MB stack size on "safety" threads.
7131static unsigned SafetyStackThreadSize = 8 << 20;
7132
7133namespace clang {
7134
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007135bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007136 unsigned Size) {
7137 if (!Size)
7138 Size = GetSafetyThreadStackSize();
7139 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007140 return CRC.RunSafelyOnThread(Fn, Size);
7141 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007142}
7143
7144unsigned GetSafetyThreadStackSize() {
7145 return SafetyStackThreadSize;
7146}
7147
7148void SetSafetyThreadStackSize(unsigned Value) {
7149 SafetyStackThreadSize = Value;
7150}
7151
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007152}
Guy Benyei11169dd2012-12-18 14:30:41 +00007153
7154void clang::setThreadBackgroundPriority() {
7155 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7156 return;
7157
Alp Toker1a86ad22014-07-06 06:24:00 +00007158#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007159 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7160#endif
7161}
7162
7163void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7164 if (!Unit)
7165 return;
7166
7167 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7168 DEnd = Unit->stored_diag_end();
7169 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007170 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007171 CXString Msg = clang_formatDiagnostic(&Diag,
7172 clang_defaultDiagnosticDisplayOptions());
7173 fprintf(stderr, "%s\n", clang_getCString(Msg));
7174 clang_disposeString(Msg);
7175 }
7176#ifdef LLVM_ON_WIN32
7177 // On Windows, force a flush, since there may be multiple copies of
7178 // stderr and stdout in the file system, all with different buffers
7179 // but writing to the same device.
7180 fflush(stderr);
7181#endif
7182}
7183
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007184MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7185 SourceLocation MacroDefLoc,
7186 CXTranslationUnit TU){
7187 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007188 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007189 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007192 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007193 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007194 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007195 if (MD) {
7196 for (MacroDirective::DefInfo
7197 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7198 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7199 return Def.getMacroInfo();
7200 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007201 }
7202
Craig Topper69186e72014-06-08 08:38:04 +00007203 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007204}
7205
Richard Smith66a81862015-05-04 02:25:31 +00007206const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007207 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007208 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007209 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007210 const IdentifierInfo *II = MacroDef->getName();
7211 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007212 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007213
7214 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7215}
7216
Richard Smith66a81862015-05-04 02:25:31 +00007217MacroDefinitionRecord *
7218cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7219 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007220 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007221 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007222 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007223 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224
7225 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007226 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007227 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7228 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007229 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230
7231 // Check that the token is inside the definition and not its argument list.
7232 SourceManager &SM = Unit->getSourceManager();
7233 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007234 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007235 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007236 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237
7238 Preprocessor &PP = Unit->getPreprocessor();
7239 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7240 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007241 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007242
Alp Toker2d57cea2014-05-17 04:53:25 +00007243 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007244 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007245 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007246
7247 // Check that the identifier is not one of the macro arguments.
7248 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007249 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007250
Richard Smith20e883e2015-04-29 23:20:19 +00007251 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007252 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007253 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007254
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007255 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007256}
7257
Richard Smith66a81862015-05-04 02:25:31 +00007258MacroDefinitionRecord *
7259cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7260 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007262 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007263
7264 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007265 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007266 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007267 Preprocessor &PP = Unit->getPreprocessor();
7268 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7271 Token Tok;
7272 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007273 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007274
7275 return checkForMacroInMacroDefinition(MI, Tok, TU);
7276}
7277
Guy Benyei11169dd2012-12-18 14:30:41 +00007278extern "C" {
7279
7280CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007281 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007282}
7283
7284} // end: extern "C"
7285
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007286Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7287 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007288 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007289 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007290 if (Unit->isMainFileAST())
7291 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007292 return *this;
7293 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007294 } else {
7295 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007296 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007297 return *this;
7298}
7299
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007300Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7301 *this << FE->getName();
7302 return *this;
7303}
7304
7305Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7306 CXString cursorName = clang_getCursorDisplayName(cursor);
7307 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7308 clang_disposeString(cursorName);
7309 return *this;
7310}
7311
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007312Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7313 CXFile File;
7314 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007315 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007316 CXString FileName = clang_getFileName(File);
7317 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7318 clang_disposeString(FileName);
7319 return *this;
7320}
7321
7322Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7323 CXSourceLocation BLoc = clang_getRangeStart(range);
7324 CXSourceLocation ELoc = clang_getRangeEnd(range);
7325
7326 CXFile BFile;
7327 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007328 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329
7330 CXFile EFile;
7331 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007332 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007333
7334 CXString BFileName = clang_getFileName(BFile);
7335 if (BFile == EFile) {
7336 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7337 BLine, BColumn, ELine, EColumn);
7338 } else {
7339 CXString EFileName = clang_getFileName(EFile);
7340 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7341 BLine, BColumn)
7342 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7343 ELine, EColumn);
7344 clang_disposeString(EFileName);
7345 }
7346 clang_disposeString(BFileName);
7347 return *this;
7348}
7349
7350Logger &cxindex::Logger::operator<<(CXString Str) {
7351 *this << clang_getCString(Str);
7352 return *this;
7353}
7354
7355Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7356 LogOS << Fmt;
7357 return *this;
7358}
7359
Chandler Carruth37ad2582014-06-27 15:14:39 +00007360static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7361
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007362cxindex::Logger::~Logger() {
7363 LogOS.flush();
7364
Chandler Carruth37ad2582014-06-27 15:14:39 +00007365 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007366
7367 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7368
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007369 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007370 OS << "[libclang:" << Name << ':';
7371
Alp Toker1a86ad22014-07-06 06:24:00 +00007372#ifdef USE_DARWIN_THREADS
7373 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007374 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7375 OS << tid << ':';
7376#endif
7377
7378 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7379 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007380 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007381
7382 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007383 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007384 OS << "--------------------------------------------------\n";
7385 }
7386}