blob: e5e2730e68fbaa5adef0d7a4115ba2778571d328 [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
Michael Wonge710d542015-08-07 16:16:36 +00002055void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2056 Visitor->AddStmt(C->getDevice());
2057}
2058
Alexey Bataev756c1962013-09-24 03:17:45 +00002059template<typename T>
2060void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002061 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002062 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002063 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002064}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002065
2066void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002067 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002068 for (const auto *E : C->private_copies()) {
2069 Visitor->AddStmt(E);
2070 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002072void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2073 const OMPFirstprivateClause *C) {
2074 VisitOMPClauseList(C);
2075}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002076void OMPClauseEnqueue::VisitOMPLastprivateClause(
2077 const OMPLastprivateClause *C) {
2078 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002079 for (auto *E : C->private_copies()) {
2080 Visitor->AddStmt(E);
2081 }
2082 for (auto *E : C->source_exprs()) {
2083 Visitor->AddStmt(E);
2084 }
2085 for (auto *E : C->destination_exprs()) {
2086 Visitor->AddStmt(E);
2087 }
2088 for (auto *E : C->assignment_ops()) {
2089 Visitor->AddStmt(E);
2090 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002091}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002092void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002093 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002094}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002095void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2096 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002097 for (auto *E : C->lhs_exprs()) {
2098 Visitor->AddStmt(E);
2099 }
2100 for (auto *E : C->rhs_exprs()) {
2101 Visitor->AddStmt(E);
2102 }
2103 for (auto *E : C->reduction_ops()) {
2104 Visitor->AddStmt(E);
2105 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002106}
Alexander Musman8dba6642014-04-22 13:09:42 +00002107void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2108 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002109 for (const auto *E : C->privates()) {
2110 Visitor->AddStmt(E);
2111 }
Alexander Musman3276a272015-03-21 10:12:56 +00002112 for (const auto *E : C->inits()) {
2113 Visitor->AddStmt(E);
2114 }
2115 for (const auto *E : C->updates()) {
2116 Visitor->AddStmt(E);
2117 }
2118 for (const auto *E : C->finals()) {
2119 Visitor->AddStmt(E);
2120 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002121 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002122 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002123}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002124void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2125 VisitOMPClauseList(C);
2126 Visitor->AddStmt(C->getAlignment());
2127}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002128void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2129 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002130 for (auto *E : C->source_exprs()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (auto *E : C->destination_exprs()) {
2134 Visitor->AddStmt(E);
2135 }
2136 for (auto *E : C->assignment_ops()) {
2137 Visitor->AddStmt(E);
2138 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002139}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002140void
2141OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2142 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002143 for (auto *E : C->source_exprs()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (auto *E : C->destination_exprs()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (auto *E : C->assignment_ops()) {
2150 Visitor->AddStmt(E);
2151 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002152}
Alexey Bataev6125da92014-07-21 11:26:11 +00002153void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2154 VisitOMPClauseList(C);
2155}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002156void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2157 VisitOMPClauseList(C);
2158}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002159}
Alexey Bataev756c1962013-09-24 03:17:45 +00002160
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002161void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2162 unsigned size = WL.size();
2163 OMPClauseEnqueue Visitor(this);
2164 Visitor.Visit(S);
2165 if (size == WL.size())
2166 return;
2167 // Now reverse the entries we just added. This will match the DFS
2168 // ordering performed by the worklist.
2169 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2170 std::reverse(I, E);
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddDecl(B->getBlockDecl());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 EnqueueChildren(E);
2180 AddTypeLoc(E->getTypeSourceInfo());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002183 for (auto &I : llvm::reverse(S->body()))
2184 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002185}
2186void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 AddStmt(S->getSubStmt());
2189 AddDeclarationNameInfo(S);
2190 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2191 AddNestedNameSpecifierLoc(QualifierLoc);
2192}
2193
2194void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2197 AddDeclarationNameInfo(E);
2198 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2199 AddNestedNameSpecifierLoc(QualifierLoc);
2200 if (!E->isImplicitAccess())
2201 AddStmt(E->getBase());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 // Enqueue the initializer , if any.
2205 AddStmt(E->getInitializer());
2206 // Enqueue the array size, if any.
2207 AddStmt(E->getArraySize());
2208 // Enqueue the allocated type.
2209 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2210 // Enqueue the placement arguments.
2211 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2212 AddStmt(E->getPlacementArg(I-1));
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2216 AddStmt(CE->getArg(I-1));
2217 AddStmt(CE->getCallee());
2218 AddStmt(CE->getArg(0));
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2221 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 // Visit the name of the type being destroyed.
2223 AddTypeLoc(E->getDestroyedTypeInfo());
2224 // Visit the scope type that looks disturbingly like the nested-name-specifier
2225 // but isn't.
2226 AddTypeLoc(E->getScopeTypeInfo());
2227 // Visit the nested-name-specifier.
2228 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2229 AddNestedNameSpecifierLoc(QualifierLoc);
2230 // Visit base expression.
2231 AddStmt(E->getBase());
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2234 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddTypeLoc(E->getTypeSourceInfo());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2238 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 EnqueueChildren(E);
2240 AddTypeLoc(E->getTypeSourceInfo());
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 EnqueueChildren(E);
2244 if (E->isTypeOperand())
2245 AddTypeLoc(E->getTypeOperandSourceInfo());
2246}
2247
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2249 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 EnqueueChildren(E);
2251 AddTypeLoc(E->getTypeSourceInfo());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 if (E->isTypeOperand())
2256 AddTypeLoc(E->getTypeOperandSourceInfo());
2257}
2258
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 EnqueueChildren(S);
2261 AddDecl(S->getExceptionDecl());
2262}
2263
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002264void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002265 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002266 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002267 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002268}
2269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 if (DR->hasExplicitTemplateArgs()) {
2272 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2273 }
2274 WL.push_back(DeclRefExprParts(DR, Parent));
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2277 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2279 AddDeclarationNameInfo(E);
2280 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 unsigned size = WL.size();
2284 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002285 for (const auto *D : S->decls()) {
2286 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 isFirst = false;
2288 }
2289 if (size == WL.size())
2290 return;
2291 // Now reverse the entries we just added. This will match the DFS
2292 // ordering performed by the worklist.
2293 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2294 std::reverse(I, E);
2295}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 D = E->designators_rbegin(), DEnd = E->designators_rend();
2300 D != DEnd; ++D) {
2301 if (D->isFieldDesignator()) {
2302 if (FieldDecl *Field = D->getField())
2303 AddMemberRef(Field, D->getFieldLoc());
2304 continue;
2305 }
2306 if (D->isArrayDesignator()) {
2307 AddStmt(E->getArrayIndex(*D));
2308 continue;
2309 }
2310 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2311 AddStmt(E->getArrayRangeEnd(*D));
2312 AddStmt(E->getArrayRangeStart(*D));
2313 }
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 EnqueueChildren(E);
2317 AddTypeLoc(E->getTypeInfoAsWritten());
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 AddStmt(FS->getBody());
2321 AddStmt(FS->getInc());
2322 AddStmt(FS->getCond());
2323 AddDecl(FS->getConditionVariable());
2324 AddStmt(FS->getInit());
2325}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2328}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 AddStmt(If->getElse());
2331 AddStmt(If->getThen());
2332 AddStmt(If->getCond());
2333 AddDecl(If->getConditionVariable());
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 // We care about the syntactic form of the initializer list, only.
2337 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2338 IE = Syntactic;
2339 EnqueueChildren(IE);
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 WL.push_back(MemberExprParts(M, Parent));
2343
2344 // If the base of the member access expression is an implicit 'this', don't
2345 // visit it.
2346 // FIXME: If we ever want to show these implicit accesses, this will be
2347 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002348 if (M->isImplicitAccess())
2349 return;
2350
2351 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2352 // real field that that we are interested in.
2353 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2354 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2355 if (FD->isAnonymousStructOrUnion()) {
2356 AddStmt(SubME->getBase());
2357 return;
2358 }
2359 }
2360 }
2361
2362 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 AddTypeLoc(E->getEncodedTypeSourceInfo());
2366}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002367void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002368 EnqueueChildren(M);
2369 AddTypeLoc(M->getClassReceiverTypeInfo());
2370}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 // Visit the components of the offsetof expression.
2373 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2374 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2375 const OffsetOfNode &Node = E->getComponent(I-1);
2376 switch (Node.getKind()) {
2377 case OffsetOfNode::Array:
2378 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2379 break;
2380 case OffsetOfNode::Field:
2381 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2382 break;
2383 case OffsetOfNode::Identifier:
2384 case OffsetOfNode::Base:
2385 continue;
2386 }
2387 }
2388 // Visit the type into which we're computing the offset.
2389 AddTypeLoc(E->getTypeSourceInfo());
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2393 WL.push_back(OverloadExprParts(E, Parent));
2394}
2395void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 EnqueueChildren(E);
2398 if (E->isArgumentType())
2399 AddTypeLoc(E->getArgumentTypeInfo());
2400}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 EnqueueChildren(S);
2403}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002404void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002405 AddStmt(S->getBody());
2406 AddStmt(S->getCond());
2407 AddDecl(S->getConditionVariable());
2408}
2409
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 AddStmt(W->getBody());
2412 AddStmt(W->getCond());
2413 AddDecl(W->getConditionVariable());
2414}
2415
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 for (unsigned I = E->getNumArgs(); I > 0; --I)
2418 AddTypeLoc(E->getArg(I-1));
2419}
2420
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 AddTypeLoc(E->getQueriedTypeSourceInfo());
2423}
2424
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 EnqueueChildren(E);
2427}
2428
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 VisitOverloadExpr(U);
2431 if (!U->isImplicitAccess())
2432 AddStmt(U->getBase());
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 AddStmt(E->getSubExpr());
2436 AddTypeLoc(E->getWrittenTypeInfo());
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 WL.push_back(SizeOfPackExprParts(E, Parent));
2440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 // If the opaque value has a source expression, just transparently
2443 // visit that. This is useful for (e.g.) pseudo-object expressions.
2444 if (Expr *SourceExpr = E->getSourceExpr())
2445 return Visit(SourceExpr);
2446}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 AddStmt(E->getBody());
2449 WL.push_back(LambdaExprParts(E, Parent));
2450}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 // Treat the expression like its syntactic form.
2453 Visit(E->getSyntacticForm());
2454}
2455
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002456void EnqueueVisitor::VisitOMPExecutableDirective(
2457 const OMPExecutableDirective *D) {
2458 EnqueueChildren(D);
2459 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2460 E = D->clauses().end();
2461 I != E; ++I)
2462 EnqueueChildren(*I);
2463}
2464
Alexander Musman3aaab662014-08-19 11:27:13 +00002465void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2466 VisitOMPExecutableDirective(D);
2467}
2468
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002469void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2470 VisitOMPExecutableDirective(D);
2471}
2472
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002473void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002474 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002475}
2476
Alexey Bataevf29276e2014-06-18 04:14:57 +00002477void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002478 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002479}
2480
Alexander Musmanf82886e2014-09-18 05:12:34 +00002481void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2482 VisitOMPLoopDirective(D);
2483}
2484
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002485void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2486 VisitOMPExecutableDirective(D);
2487}
2488
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002489void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2490 VisitOMPExecutableDirective(D);
2491}
2492
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002493void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2494 VisitOMPExecutableDirective(D);
2495}
2496
Alexander Musman80c22892014-07-17 08:54:58 +00002497void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002501void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503 AddDeclarationNameInfo(D);
2504}
2505
Alexey Bataev4acb8592014-07-07 13:01:15 +00002506void
2507EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002508 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002509}
2510
Alexander Musmane4e893b2014-09-23 09:33:00 +00002511void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2512 const OMPParallelForSimdDirective *D) {
2513 VisitOMPLoopDirective(D);
2514}
2515
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002516void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2517 const OMPParallelSectionsDirective *D) {
2518 VisitOMPExecutableDirective(D);
2519}
2520
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002521void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2522 VisitOMPExecutableDirective(D);
2523}
2524
Alexey Bataev68446b72014-07-18 07:47:19 +00002525void
2526EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2527 VisitOMPExecutableDirective(D);
2528}
2529
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002530void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev2df347a2014-07-18 10:17:07 +00002534void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002538void EnqueueVisitor::VisitOMPTaskgroupDirective(
2539 const OMPTaskgroupDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataev6125da92014-07-21 11:26:11 +00002543void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002547void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2548 VisitOMPExecutableDirective(D);
2549}
2550
Alexey Bataev0162e452014-07-22 10:10:35 +00002551void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002555void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Michael Wong65f367f2015-07-21 13:44:28 +00002559void EnqueueVisitor::VisitOMPTargetDataDirective(const
2560 OMPTargetDataDirective *D) {
2561 VisitOMPExecutableDirective(D);
2562}
2563
Alexey Bataev13314bf2014-10-09 04:18:56 +00002564void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002568void EnqueueVisitor::VisitOMPCancellationPointDirective(
2569 const OMPCancellationPointDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexey Bataev80909872015-07-02 11:25:17 +00002573void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002577void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002578 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2579}
2580
2581bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2582 if (RegionOfInterest.isValid()) {
2583 SourceRange Range = getRawCursorExtent(C);
2584 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2585 return false;
2586 }
2587 return true;
2588}
2589
2590bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2591 while (!WL.empty()) {
2592 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002593 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002594
2595 // Set the Parent field, then back to its old value once we're done.
2596 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2597
2598 switch (LI.getKind()) {
2599 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002600 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 if (!D)
2602 continue;
2603
2604 // For now, perform default visitation for Decls.
2605 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2606 cast<DeclVisit>(&LI)->isFirst())))
2607 return true;
2608
2609 continue;
2610 }
2611 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2612 const ASTTemplateArgumentListInfo *ArgList =
2613 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2614 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2615 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2616 Arg != ArgEnd; ++Arg) {
2617 if (VisitTemplateArgumentLoc(*Arg))
2618 return true;
2619 }
2620 continue;
2621 }
2622 case VisitorJob::TypeLocVisitKind: {
2623 // Perform default visitation for TypeLocs.
2624 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2625 return true;
2626 continue;
2627 }
2628 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002629 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 if (LabelStmt *stmt = LS->getStmt()) {
2631 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2632 TU))) {
2633 return true;
2634 }
2635 }
2636 continue;
2637 }
2638
2639 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2640 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2641 if (VisitNestedNameSpecifierLoc(V->get()))
2642 return true;
2643 continue;
2644 }
2645
2646 case VisitorJob::DeclarationNameInfoVisitKind: {
2647 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2648 ->get()))
2649 return true;
2650 continue;
2651 }
2652 case VisitorJob::MemberRefVisitKind: {
2653 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2654 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2655 return true;
2656 continue;
2657 }
2658 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002659 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 if (!S)
2661 continue;
2662
2663 // Update the current cursor.
2664 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2665 if (!IsInRegionOfInterest(Cursor))
2666 continue;
2667 switch (Visitor(Cursor, Parent, ClientData)) {
2668 case CXChildVisit_Break: return true;
2669 case CXChildVisit_Continue: break;
2670 case CXChildVisit_Recurse:
2671 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002672 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 EnqueueWorkList(WL, S);
2674 break;
2675 }
2676 continue;
2677 }
2678 case VisitorJob::MemberExprPartsKind: {
2679 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002680 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002681
2682 // Visit the nested-name-specifier
2683 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2684 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2685 return true;
2686
2687 // Visit the declaration name.
2688 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2689 return true;
2690
2691 // Visit the explicitly-specified template arguments, if any.
2692 if (M->hasExplicitTemplateArgs()) {
2693 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2694 *ArgEnd = Arg + M->getNumTemplateArgs();
2695 Arg != ArgEnd; ++Arg) {
2696 if (VisitTemplateArgumentLoc(*Arg))
2697 return true;
2698 }
2699 }
2700 continue;
2701 }
2702 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002703 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 // Visit nested-name-specifier, if present.
2705 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2706 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2707 return true;
2708 // Visit declaration name.
2709 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2710 return true;
2711 continue;
2712 }
2713 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 // Visit the nested-name-specifier.
2716 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2717 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2718 return true;
2719 // Visit the declaration name.
2720 if (VisitDeclarationNameInfo(O->getNameInfo()))
2721 return true;
2722 // Visit the overloaded declaration reference.
2723 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2724 return true;
2725 continue;
2726 }
2727 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002728 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 NamedDecl *Pack = E->getPack();
2730 if (isa<TemplateTypeParmDecl>(Pack)) {
2731 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2732 E->getPackLoc(), TU)))
2733 return true;
2734
2735 continue;
2736 }
2737
2738 if (isa<TemplateTemplateParmDecl>(Pack)) {
2739 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2740 E->getPackLoc(), TU)))
2741 return true;
2742
2743 continue;
2744 }
2745
2746 // Non-type template parameter packs and function parameter packs are
2747 // treated like DeclRefExpr cursors.
2748 continue;
2749 }
2750
2751 case VisitorJob::LambdaExprPartsKind: {
2752 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002753 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2755 CEnd = E->explicit_capture_end();
2756 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002757 // FIXME: Lambda init-captures.
2758 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002760
Guy Benyei11169dd2012-12-18 14:30:41 +00002761 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2762 C->getLocation(),
2763 TU)))
2764 return true;
2765 }
2766
2767 // Visit parameters and return type, if present.
2768 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2769 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2770 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2771 // Visit the whole type.
2772 if (Visit(TL))
2773 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002774 } else if (FunctionProtoTypeLoc Proto =
2775 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 if (E->hasExplicitParameters()) {
2777 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002778 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2779 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002780 return true;
2781 } else {
2782 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002783 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 return true;
2785 }
2786 }
2787 }
2788 break;
2789 }
2790
2791 case VisitorJob::PostChildrenVisitKind:
2792 if (PostChildrenVisitor(Parent, ClientData))
2793 return true;
2794 break;
2795 }
2796 }
2797 return false;
2798}
2799
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002800bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002801 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 if (!WorkListFreeList.empty()) {
2803 WL = WorkListFreeList.back();
2804 WL->clear();
2805 WorkListFreeList.pop_back();
2806 }
2807 else {
2808 WL = new VisitorWorkList();
2809 WorkListCache.push_back(WL);
2810 }
2811 EnqueueWorkList(*WL, S);
2812 bool result = RunVisitorWorkList(*WL);
2813 WorkListFreeList.push_back(WL);
2814 return result;
2815}
2816
2817namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002818typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002819RefNamePieces
2820buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2821 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2822 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002823 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2824 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2825 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2826
2827 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2828
2829 RefNamePieces Pieces;
2830
2831 if (WantQualifier && QLoc.isValid())
2832 Pieces.push_back(QLoc);
2833
2834 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2835 Pieces.push_back(NI.getLoc());
2836
2837 if (WantTemplateArgs && TemplateArgs)
2838 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2839 TemplateArgs->RAngleLoc));
2840
2841 if (Kind == DeclarationName::CXXOperatorName) {
2842 Pieces.push_back(SourceLocation::getFromRawEncoding(
2843 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2844 Pieces.push_back(SourceLocation::getFromRawEncoding(
2845 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2846 }
2847
2848 if (WantSinglePiece) {
2849 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2850 Pieces.clear();
2851 Pieces.push_back(R);
2852 }
2853
2854 return Pieces;
2855}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002856}
Guy Benyei11169dd2012-12-18 14:30:41 +00002857
2858//===----------------------------------------------------------------------===//
2859// Misc. API hooks.
2860//===----------------------------------------------------------------------===//
2861
Chad Rosier05c71aa2013-03-27 18:28:23 +00002862static void fatal_error_handler(void *user_data, const std::string& reason,
2863 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 // Write the result out to stderr avoiding errs() because raw_ostreams can
2865 // call report_fatal_error.
2866 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2867 ::abort();
2868}
2869
Chandler Carruth66660742014-06-27 16:37:27 +00002870namespace {
2871struct RegisterFatalErrorHandler {
2872 RegisterFatalErrorHandler() {
2873 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2874 }
2875};
2876}
2877
2878static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2879
Guy Benyei11169dd2012-12-18 14:30:41 +00002880extern "C" {
2881CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2882 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 // We use crash recovery to make some of our APIs more reliable, implicitly
2884 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002885 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2886 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002887
Chandler Carruth66660742014-06-27 16:37:27 +00002888 // Look through the managed static to trigger construction of the managed
2889 // static which registers our fatal error handler. This ensures it is only
2890 // registered once.
2891 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002892
Adrian Prantlbc068582015-07-08 01:00:30 +00002893 // Initialize targets for clang module support.
2894 llvm::InitializeAllTargets();
2895 llvm::InitializeAllTargetMCs();
2896 llvm::InitializeAllAsmPrinters();
2897 llvm::InitializeAllAsmParsers();
2898
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002899 CIndexer *CIdxr = new CIndexer();
2900
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 if (excludeDeclarationsFromPCH)
2902 CIdxr->setOnlyLocalDecls();
2903 if (displayDiagnostics)
2904 CIdxr->setDisplayDiagnostics();
2905
2906 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2907 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2908 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2909 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2910 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2911 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2912
2913 return CIdxr;
2914}
2915
2916void clang_disposeIndex(CXIndex CIdx) {
2917 if (CIdx)
2918 delete static_cast<CIndexer *>(CIdx);
2919}
2920
2921void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2922 if (CIdx)
2923 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2924}
2925
2926unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2927 if (CIdx)
2928 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2929 return 0;
2930}
2931
2932void clang_toggleCrashRecovery(unsigned isEnabled) {
2933 if (isEnabled)
2934 llvm::CrashRecoveryContext::Enable();
2935 else
2936 llvm::CrashRecoveryContext::Disable();
2937}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002938
Guy Benyei11169dd2012-12-18 14:30:41 +00002939CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2940 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002941 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002942 enum CXErrorCode Result =
2943 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002944 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002945 assert((TU && Result == CXError_Success) ||
2946 (!TU && Result != CXError_Success));
2947 return TU;
2948}
2949
2950enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2951 const char *ast_filename,
2952 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002953 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002954 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002955
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002956 if (!CIdx || !ast_filename || !out_TU)
2957 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002958
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002959 LOG_FUNC_SECTION {
2960 *Log << ast_filename;
2961 }
2962
Guy Benyei11169dd2012-12-18 14:30:41 +00002963 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2964 FileSystemOptions FileSystemOpts;
2965
Justin Bognerd512c1e2014-10-15 00:33:06 +00002966 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2967 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002968 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002969 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
2970 FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002971 /*CaptureDiagnostics=*/true,
2972 /*AllowPCHWithCompilerErrors=*/true,
2973 /*UserFilesAreVolatile=*/true);
2974 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002976}
2977
2978unsigned clang_defaultEditingTranslationUnitOptions() {
2979 return CXTranslationUnit_PrecompiledPreamble |
2980 CXTranslationUnit_CacheCompletionResults;
2981}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982
Guy Benyei11169dd2012-12-18 14:30:41 +00002983CXTranslationUnit
2984clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2985 const char *source_filename,
2986 int num_command_line_args,
2987 const char * const *command_line_args,
2988 unsigned num_unsaved_files,
2989 struct CXUnsavedFile *unsaved_files) {
2990 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2991 return clang_parseTranslationUnit(CIdx, source_filename,
2992 command_line_args, num_command_line_args,
2993 unsaved_files, num_unsaved_files,
2994 Options);
2995}
2996
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00002997static CXErrorCode
2998clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
2999 const char *const *command_line_args,
3000 int num_command_line_args,
3001 ArrayRef<CXUnsavedFile> unsaved_files,
3002 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003003 // Set up the initial return values.
3004 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003005 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003006
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003007 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003008 if (!CIdx || !out_TU)
3009 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3012
3013 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3014 setThreadBackgroundPriority();
3015
3016 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3017 // FIXME: Add a flag for modules.
3018 TranslationUnitKind TUKind
3019 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003020 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 = options & CXTranslationUnit_CacheCompletionResults;
3022 bool IncludeBriefCommentsInCodeCompletion
3023 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3024 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3025 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3026
3027 // Configure the diagnostics.
3028 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003029 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003030
3031 // Recover resources if we crash before exiting this function.
3032 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3033 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003034 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003035
Ahmed Charlesb8984322014-03-07 20:03:18 +00003036 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3037 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003038
3039 // Recover resources if we crash before exiting this function.
3040 llvm::CrashRecoveryContextCleanupRegistrar<
3041 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3042
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003043 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003044 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003045 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003046 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 }
3048
Ahmed Charlesb8984322014-03-07 20:03:18 +00003049 std::unique_ptr<std::vector<const char *>> Args(
3050 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003051
3052 // Recover resources if we crash before exiting this method.
3053 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3054 ArgsCleanup(Args.get());
3055
3056 // Since the Clang C library is primarily used by batch tools dealing with
3057 // (often very broken) source code, where spell-checking can have a
3058 // significant negative impact on performance (particularly when
3059 // precompiled headers are involved), we disable it by default.
3060 // Only do this if we haven't found a spell-checking-related argument.
3061 bool FoundSpellCheckingArgument = false;
3062 for (int I = 0; I != num_command_line_args; ++I) {
3063 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3064 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3065 FoundSpellCheckingArgument = true;
3066 break;
3067 }
3068 }
3069 if (!FoundSpellCheckingArgument)
3070 Args->push_back("-fno-spell-checking");
3071
3072 Args->insert(Args->end(), command_line_args,
3073 command_line_args + num_command_line_args);
3074
3075 // The 'source_filename' argument is optional. If the caller does not
3076 // specify it then it is assumed that the source file is specified
3077 // in the actual argument list.
3078 // Put the source file after command_line_args otherwise if '-x' flag is
3079 // present it will be unused.
3080 if (source_filename)
3081 Args->push_back(source_filename);
3082
3083 // Do we need the detailed preprocessing record?
3084 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3085 Args->push_back("-Xclang");
3086 Args->push_back("-detailed-preprocessing-record");
3087 }
3088
3089 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003090 std::unique_ptr<ASTUnit> ErrUnit;
3091 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003092 Args->data(), Args->data() + Args->size(),
3093 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003094 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3095 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3096 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3097 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3098 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3099 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003100
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003101 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003102 if (!Unit && !ErrUnit)
3103 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003104
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 if (NumErrors != Diags->getClient()->getNumErrors()) {
3106 // Make sure to check that 'Unit' is non-NULL.
3107 if (CXXIdx->getDisplayDiagnostics())
3108 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3109 }
3110
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003111 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3112 return CXError_ASTReadError;
3113
3114 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3115 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003116}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117
3118CXTranslationUnit
3119clang_parseTranslationUnit(CXIndex CIdx,
3120 const char *source_filename,
3121 const char *const *command_line_args,
3122 int num_command_line_args,
3123 struct CXUnsavedFile *unsaved_files,
3124 unsigned num_unsaved_files,
3125 unsigned options) {
3126 CXTranslationUnit TU;
3127 enum CXErrorCode Result = clang_parseTranslationUnit2(
3128 CIdx, source_filename, command_line_args, num_command_line_args,
3129 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003130 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003131 assert((TU && Result == CXError_Success) ||
3132 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003133 return TU;
3134}
3135
3136enum CXErrorCode clang_parseTranslationUnit2(
3137 CXIndex CIdx,
3138 const char *source_filename,
3139 const char *const *command_line_args,
3140 int num_command_line_args,
3141 struct CXUnsavedFile *unsaved_files,
3142 unsigned num_unsaved_files,
3143 unsigned options,
3144 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003145 LOG_FUNC_SECTION {
3146 *Log << source_filename << ": ";
3147 for (int i = 0; i != num_command_line_args; ++i)
3148 *Log << command_line_args[i] << " ";
3149 }
3150
Alp Toker9d85b182014-07-07 01:23:14 +00003151 if (num_unsaved_files && !unsaved_files)
3152 return CXError_InvalidArguments;
3153
Alp Toker5c532982014-07-07 22:42:03 +00003154 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003155 auto ParseTranslationUnitImpl = [=, &result] {
3156 result = clang_parseTranslationUnit_Impl(
3157 CIdx, source_filename, command_line_args, num_command_line_args,
3158 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3159 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 llvm::CrashRecoveryContext CRC;
3161
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003162 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3164 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3165 fprintf(stderr, " 'command_line_args' : [");
3166 for (int i = 0; i != num_command_line_args; ++i) {
3167 if (i)
3168 fprintf(stderr, ", ");
3169 fprintf(stderr, "'%s'", command_line_args[i]);
3170 }
3171 fprintf(stderr, "],\n");
3172 fprintf(stderr, " 'unsaved_files' : [");
3173 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3174 if (i)
3175 fprintf(stderr, ", ");
3176 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3177 unsaved_files[i].Length);
3178 }
3179 fprintf(stderr, "],\n");
3180 fprintf(stderr, " 'options' : %d,\n", options);
3181 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003182
3183 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003185 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003186 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 }
Alp Toker5c532982014-07-07 22:42:03 +00003188
3189 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003190}
3191
3192unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3193 return CXSaveTranslationUnit_None;
3194}
3195
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003196static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3197 const char *FileName,
3198 unsigned options) {
3199 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3201 setThreadBackgroundPriority();
3202
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003203 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3204 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003205}
3206
3207int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3208 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003209 LOG_FUNC_SECTION {
3210 *Log << TU << ' ' << FileName;
3211 }
3212
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003213 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003214 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003216 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003217
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003218 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3220 if (!CXXUnit->hasSema())
3221 return CXSaveError_InvalidTU;
3222
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003223 CXSaveError result;
3224 auto SaveTranslationUnitImpl = [=, &result]() {
3225 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3226 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003227
3228 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3229 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003230 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003231
3232 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3233 PrintLibclangResourceUsage(TU);
3234
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003235 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 }
3237
3238 // We have an AST that has invalid nodes due to compiler errors.
3239 // Use a crash recovery thread for protection.
3240
3241 llvm::CrashRecoveryContext CRC;
3242
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003243 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3245 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3246 fprintf(stderr, " 'options' : %d,\n", options);
3247 fprintf(stderr, "}\n");
3248
3249 return CXSaveError_Unknown;
3250
3251 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3252 PrintLibclangResourceUsage(TU);
3253 }
3254
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003255 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256}
3257
3258void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3259 if (CTUnit) {
3260 // If the translation unit has been marked as unsafe to free, just discard
3261 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003262 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3263 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 return;
3265
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003266 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003267 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3269 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003270 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 delete CTUnit;
3272 }
3273}
3274
3275unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3276 return CXReparse_None;
3277}
3278
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003279static CXErrorCode
3280clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3281 ArrayRef<CXUnsavedFile> unsaved_files,
3282 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003283 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003284 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003285 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003286 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003287 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
3289 // Reset the associated diagnostics.
3290 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003291 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003293 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3295 setThreadBackgroundPriority();
3296
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003297 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003299
3300 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3301 new std::vector<ASTUnit::RemappedFile>());
3302
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 // Recover resources if we crash before exiting this function.
3304 llvm::CrashRecoveryContextCleanupRegistrar<
3305 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003306
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003307 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003308 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003309 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003310 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003312
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003313 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3314 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003315 return CXError_Success;
3316 if (isASTReadError(CXXUnit))
3317 return CXError_ASTReadError;
3318 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003319}
3320
3321int clang_reparseTranslationUnit(CXTranslationUnit TU,
3322 unsigned num_unsaved_files,
3323 struct CXUnsavedFile *unsaved_files,
3324 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003325 LOG_FUNC_SECTION {
3326 *Log << TU;
3327 }
3328
Alp Toker9d85b182014-07-07 01:23:14 +00003329 if (num_unsaved_files && !unsaved_files)
3330 return CXError_InvalidArguments;
3331
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003332 CXErrorCode result;
3333 auto ReparseTranslationUnitImpl = [=, &result]() {
3334 result = clang_reparseTranslationUnit_Impl(
3335 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3336 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003337
3338 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003339 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003340 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 }
3342
3343 llvm::CrashRecoveryContext CRC;
3344
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003345 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003347 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003348 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3350 PrintLibclangResourceUsage(TU);
3351
Alp Toker5c532982014-07-07 22:42:03 +00003352 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353}
3354
3355
3356CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003357 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003358 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003359 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003360 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003361
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003362 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364}
3365
3366CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003367 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003368 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003369 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003370 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003371
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003372 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3374}
3375
3376} // end: extern "C"
3377
3378//===----------------------------------------------------------------------===//
3379// CXFile Operations.
3380//===----------------------------------------------------------------------===//
3381
3382extern "C" {
3383CXString clang_getFileName(CXFile SFile) {
3384 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003385 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003386
3387 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003388 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003389}
3390
3391time_t clang_getFileTime(CXFile SFile) {
3392 if (!SFile)
3393 return 0;
3394
3395 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3396 return FEnt->getModificationTime();
3397}
3398
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003399CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003400 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003401 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003402 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003403 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003404
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003405 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003406
3407 FileManager &FMgr = CXXUnit->getFileManager();
3408 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3409}
3410
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003411unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3412 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003413 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003414 LOG_BAD_TU(TU);
3415 return 0;
3416 }
3417
3418 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 return 0;
3420
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003421 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 FileEntry *FEnt = static_cast<FileEntry *>(file);
3423 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3424 .isFileMultipleIncludeGuarded(FEnt);
3425}
3426
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003427int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3428 if (!file || !outID)
3429 return 1;
3430
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003431 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003432 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3433 outID->data[0] = ID.getDevice();
3434 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003435 outID->data[2] = FEnt->getModificationTime();
3436 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003437}
3438
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003439int clang_File_isEqual(CXFile file1, CXFile file2) {
3440 if (file1 == file2)
3441 return true;
3442
3443 if (!file1 || !file2)
3444 return false;
3445
3446 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3447 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3448 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3449}
3450
Guy Benyei11169dd2012-12-18 14:30:41 +00003451} // end: extern "C"
3452
3453//===----------------------------------------------------------------------===//
3454// CXCursor Operations.
3455//===----------------------------------------------------------------------===//
3456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003457static const Decl *getDeclFromExpr(const Stmt *E) {
3458 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 return getDeclFromExpr(CE->getSubExpr());
3460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003461 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003463 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 if (PRE->isExplicitProperty())
3469 return PRE->getExplicitProperty();
3470 // It could be messaging both getter and setter as in:
3471 // ++myobj.myprop;
3472 // in which case prefer to associate the setter since it is less obvious
3473 // from inspecting the source that the setter is going to get called.
3474 if (PRE->isMessagingSetter())
3475 return PRE->getImplicitPropertySetter();
3476 return PRE->getImplicitPropertyGetter();
3477 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 if (Expr *Src = OVE->getSourceExpr())
3482 return getDeclFromExpr(Src);
3483
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 if (!CE->isElidable())
3488 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 return OME->getMethodDecl();
3491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3496 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3499 isa<ParmVarDecl>(SizeOfPack->getPack()))
3500 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003501
3502 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003503}
3504
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003505static SourceLocation getLocationFromExpr(const Expr *E) {
3506 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return getLocationFromExpr(CE->getSubExpr());
3508
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003509 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003511 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003513 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003515 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003517 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return PropRef->getLocation();
3521
3522 return E->getLocStart();
3523}
3524
3525extern "C" {
3526
3527unsigned clang_visitChildren(CXCursor parent,
3528 CXCursorVisitor visitor,
3529 CXClientData client_data) {
3530 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3531 /*VisitPreprocessorLast=*/false);
3532 return CursorVis.VisitChildren(parent);
3533}
3534
3535#ifndef __has_feature
3536#define __has_feature(x) 0
3537#endif
3538#if __has_feature(blocks)
3539typedef enum CXChildVisitResult
3540 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3541
3542static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3543 CXClientData client_data) {
3544 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3545 return block(cursor, parent);
3546}
3547#else
3548// If we are compiled with a compiler that doesn't have native blocks support,
3549// define and call the block manually, so the
3550typedef struct _CXChildVisitResult
3551{
3552 void *isa;
3553 int flags;
3554 int reserved;
3555 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3556 CXCursor);
3557} *CXCursorVisitorBlock;
3558
3559static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3560 CXClientData client_data) {
3561 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3562 return block->invoke(block, cursor, parent);
3563}
3564#endif
3565
3566
3567unsigned clang_visitChildrenWithBlock(CXCursor parent,
3568 CXCursorVisitorBlock block) {
3569 return clang_visitChildren(parent, visitWithBlock, block);
3570}
3571
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003572static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003574 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003575
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003576 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003578 if (const ObjCPropertyImplDecl *PropImpl =
3579 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003581 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003583 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003586
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003587 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 }
3589
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003590 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3595 // and returns different names. NamedDecl returns the class name and
3596 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003598
3599 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003600 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003601
3602 SmallString<1024> S;
3603 llvm::raw_svector_ostream os(S);
3604 ND->printName(os);
3605
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607}
3608
3609CXString clang_getCursorSpelling(CXCursor C) {
3610 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003611 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003612
3613 if (clang_isReference(C.kind)) {
3614 switch (C.kind) {
3615 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003616 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 }
3619 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003620 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 }
3623 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003624 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 }
3628 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003629 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003630 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
3632 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 assert(Type && "Missing type decl");
3635
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003636 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 getAsString());
3638 }
3639 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003640 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 assert(Template && "Missing template decl");
3642
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003643 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 }
3645
3646 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003647 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 assert(NS && "Missing namespace decl");
3649
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 }
3652
3653 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003654 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 assert(Field && "Missing member decl");
3656
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003657 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659
3660 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003661 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 assert(Label && "Missing label");
3663
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 }
3666
3667 case CXCursor_OverloadedDeclRef: {
3668 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003669 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3670 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003672 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003675 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 OverloadedTemplateStorage *Ovl
3677 = Storage.get<OverloadedTemplateStorage*>();
3678 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003679 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003680 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 }
3682
3683 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003684 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 assert(Var && "Missing variable decl");
3686
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003687 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689
3690 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693 }
3694
3695 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003696 const Expr *E = getCursorExpr(C);
3697
3698 if (C.kind == CXCursor_ObjCStringLiteral ||
3699 C.kind == CXCursor_StringLiteral) {
3700 const StringLiteral *SLit;
3701 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3702 SLit = OSL->getString();
3703 } else {
3704 SLit = cast<StringLiteral>(E);
3705 }
3706 SmallString<256> Buf;
3707 llvm::raw_svector_ostream OS(Buf);
3708 SLit->outputString(OS);
3709 return cxstring::createDup(OS.str());
3710 }
3711
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003712 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 if (D)
3714 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003715 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 }
3717
3718 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003719 const Stmt *S = getCursorStmt(C);
3720 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003722
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003723 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 }
3725
3726 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 ->getNameStart());
3729
3730 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 ->getNameStart());
3733
3734 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003735 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003736
3737 if (clang_isDeclaration(C.kind))
3738 return getDeclSpelling(getCursorDecl(C));
3739
3740 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003741 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003742 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 }
3744
3745 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003746 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003747 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 }
3749
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003750 if (C.kind == CXCursor_PackedAttr) {
3751 return cxstring::createRef("packed");
3752 }
3753
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003754 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003755}
3756
3757CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3758 unsigned pieceIndex,
3759 unsigned options) {
3760 if (clang_Cursor_isNull(C))
3761 return clang_getNullRange();
3762
3763 ASTContext &Ctx = getCursorContext(C);
3764
3765 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003766 const Stmt *S = getCursorStmt(C);
3767 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 if (pieceIndex > 0)
3769 return clang_getNullRange();
3770 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3771 }
3772
3773 return clang_getNullRange();
3774 }
3775
3776 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003777 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3779 if (pieceIndex >= ME->getNumSelectorLocs())
3780 return clang_getNullRange();
3781 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3782 }
3783 }
3784
3785 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3786 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003787 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3789 if (pieceIndex >= MD->getNumSelectorLocs())
3790 return clang_getNullRange();
3791 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3792 }
3793 }
3794
3795 if (C.kind == CXCursor_ObjCCategoryDecl ||
3796 C.kind == CXCursor_ObjCCategoryImplDecl) {
3797 if (pieceIndex > 0)
3798 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003799 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3801 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003802 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3804 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3805 }
3806
3807 if (C.kind == CXCursor_ModuleImportDecl) {
3808 if (pieceIndex > 0)
3809 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003810 if (const ImportDecl *ImportD =
3811 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3813 if (!Locs.empty())
3814 return cxloc::translateSourceRange(Ctx,
3815 SourceRange(Locs.front(), Locs.back()));
3816 }
3817 return clang_getNullRange();
3818 }
3819
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003820 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3821 C.kind == CXCursor_ConversionFunction) {
3822 if (pieceIndex > 0)
3823 return clang_getNullRange();
3824 if (const FunctionDecl *FD =
3825 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3826 DeclarationNameInfo FunctionName = FD->getNameInfo();
3827 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3828 }
3829 return clang_getNullRange();
3830 }
3831
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 // FIXME: A CXCursor_InclusionDirective should give the location of the
3833 // filename, but we don't keep track of this.
3834
3835 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3836 // but we don't keep track of this.
3837
3838 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3839 // but we don't keep track of this.
3840
3841 // Default handling, give the location of the cursor.
3842
3843 if (pieceIndex > 0)
3844 return clang_getNullRange();
3845
3846 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3847 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3848 return cxloc::translateSourceRange(Ctx, Loc);
3849}
3850
Eli Bendersky44a206f2014-07-31 18:04:56 +00003851CXString clang_Cursor_getMangling(CXCursor C) {
3852 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3853 return cxstring::createEmpty();
3854
Eli Bendersky44a206f2014-07-31 18:04:56 +00003855 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003856 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003857 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3858 return cxstring::createEmpty();
3859
Eli Bendersky79759592014-08-01 15:01:10 +00003860 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003861 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003862 ASTContext &Ctx = ND->getASTContext();
3863 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003864
Eli Bendersky79759592014-08-01 15:01:10 +00003865 std::string FrontendBuf;
3866 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3867 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003868
Eli Bendersky79759592014-08-01 15:01:10 +00003869 // Now apply backend mangling.
3870 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003871 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003872
3873 std::string FinalBuf;
3874 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003875 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3876 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003877
3878 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003879}
3880
Guy Benyei11169dd2012-12-18 14:30:41 +00003881CXString clang_getCursorDisplayName(CXCursor C) {
3882 if (!clang_isDeclaration(C.kind))
3883 return clang_getCursorSpelling(C);
3884
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003885 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003887 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003888
3889 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 D = FunTmpl->getTemplatedDecl();
3892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003893 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 SmallString<64> Str;
3895 llvm::raw_svector_ostream OS(Str);
3896 OS << *Function;
3897 if (Function->getPrimaryTemplate())
3898 OS << "<>";
3899 OS << "(";
3900 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3901 if (I)
3902 OS << ", ";
3903 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3904 }
3905
3906 if (Function->isVariadic()) {
3907 if (Function->getNumParams())
3908 OS << ", ";
3909 OS << "...";
3910 }
3911 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003912 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 }
3914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 SmallString<64> Str;
3917 llvm::raw_svector_ostream OS(Str);
3918 OS << *ClassTemplate;
3919 OS << "<";
3920 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3921 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3922 if (I)
3923 OS << ", ";
3924
3925 NamedDecl *Param = Params->getParam(I);
3926 if (Param->getIdentifier()) {
3927 OS << Param->getIdentifier()->getName();
3928 continue;
3929 }
3930
3931 // There is no parameter name, which makes this tricky. Try to come up
3932 // with something useful that isn't too long.
3933 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3934 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3935 else if (NonTypeTemplateParmDecl *NTTP
3936 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3937 OS << NTTP->getType().getAsString(Policy);
3938 else
3939 OS << "template<...> class";
3940 }
3941
3942 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003943 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 }
3945
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3948 // If the type was explicitly written, use that.
3949 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003950 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003951
Benjamin Kramer9170e912013-02-22 15:46:01 +00003952 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 llvm::raw_svector_ostream OS(Str);
3954 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003955 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 ClassSpec->getTemplateArgs().data(),
3957 ClassSpec->getTemplateArgs().size(),
3958 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003959 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 }
3961
3962 return clang_getCursorSpelling(C);
3963}
3964
3965CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3966 switch (Kind) {
3967 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004095 case CXCursor_ObjCSelfExpr:
4096 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004185 case CXCursor_SEHLeaveStmt:
4186 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004215 case CXCursor_PackedAttr:
4216 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004217 case CXCursor_PureAttr:
4218 return cxstring::createRef("attribute(pure)");
4219 case CXCursor_ConstAttr:
4220 return cxstring::createRef("attribute(const)");
4221 case CXCursor_NoDuplicateAttr:
4222 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004223 case CXCursor_CUDAConstantAttr:
4224 return cxstring::createRef("attribute(constant)");
4225 case CXCursor_CUDADeviceAttr:
4226 return cxstring::createRef("attribute(device)");
4227 case CXCursor_CUDAGlobalAttr:
4228 return cxstring::createRef("attribute(global)");
4229 case CXCursor_CUDAHostAttr:
4230 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004231 case CXCursor_CUDASharedAttr:
4232 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004281 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004282 return cxstring::createRef("OMPParallelDirective");
4283 case CXCursor_OMPSimdDirective:
4284 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004285 case CXCursor_OMPForDirective:
4286 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004287 case CXCursor_OMPForSimdDirective:
4288 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004289 case CXCursor_OMPSectionsDirective:
4290 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004291 case CXCursor_OMPSectionDirective:
4292 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004293 case CXCursor_OMPSingleDirective:
4294 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004295 case CXCursor_OMPMasterDirective:
4296 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004297 case CXCursor_OMPCriticalDirective:
4298 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004299 case CXCursor_OMPParallelForDirective:
4300 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004301 case CXCursor_OMPParallelForSimdDirective:
4302 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004303 case CXCursor_OMPParallelSectionsDirective:
4304 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004305 case CXCursor_OMPTaskDirective:
4306 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004307 case CXCursor_OMPTaskyieldDirective:
4308 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004309 case CXCursor_OMPBarrierDirective:
4310 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004311 case CXCursor_OMPTaskwaitDirective:
4312 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004313 case CXCursor_OMPTaskgroupDirective:
4314 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004315 case CXCursor_OMPFlushDirective:
4316 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004317 case CXCursor_OMPOrderedDirective:
4318 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004319 case CXCursor_OMPAtomicDirective:
4320 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004321 case CXCursor_OMPTargetDirective:
4322 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004323 case CXCursor_OMPTargetDataDirective:
4324 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004325 case CXCursor_OMPTeamsDirective:
4326 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004327 case CXCursor_OMPCancellationPointDirective:
4328 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004329 case CXCursor_OMPCancelDirective:
4330 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004331 case CXCursor_OverloadCandidate:
4332 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 }
4334
4335 llvm_unreachable("Unhandled CXCursorKind");
4336}
4337
4338struct GetCursorData {
4339 SourceLocation TokenBeginLoc;
4340 bool PointsAtMacroArgExpansion;
4341 bool VisitedObjCPropertyImplDecl;
4342 SourceLocation VisitedDeclaratorDeclStartLoc;
4343 CXCursor &BestCursor;
4344
4345 GetCursorData(SourceManager &SM,
4346 SourceLocation tokenBegin, CXCursor &outputCursor)
4347 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4348 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4349 VisitedObjCPropertyImplDecl = false;
4350 }
4351};
4352
4353static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4354 CXCursor parent,
4355 CXClientData client_data) {
4356 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4357 CXCursor *BestCursor = &Data->BestCursor;
4358
4359 // If we point inside a macro argument we should provide info of what the
4360 // token is so use the actual cursor, don't replace it with a macro expansion
4361 // cursor.
4362 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4363 return CXChildVisit_Recurse;
4364
4365 if (clang_isDeclaration(cursor.kind)) {
4366 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004367 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4369 if (MD->isImplicit())
4370 return CXChildVisit_Break;
4371
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004372 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4374 // Check that when we have multiple @class references in the same line,
4375 // that later ones do not override the previous ones.
4376 // If we have:
4377 // @class Foo, Bar;
4378 // source ranges for both start at '@', so 'Bar' will end up overriding
4379 // 'Foo' even though the cursor location was at 'Foo'.
4380 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4381 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004382 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4384 if (PrevID != ID &&
4385 !PrevID->isThisDeclarationADefinition() &&
4386 !ID->isThisDeclarationADefinition())
4387 return CXChildVisit_Break;
4388 }
4389
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004390 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4392 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4393 // Check that when we have multiple declarators in the same line,
4394 // that later ones do not override the previous ones.
4395 // If we have:
4396 // int Foo, Bar;
4397 // source ranges for both start at 'int', so 'Bar' will end up overriding
4398 // 'Foo' even though the cursor location was at 'Foo'.
4399 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4400 return CXChildVisit_Break;
4401 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4405 (void)PropImp;
4406 // Check that when we have multiple @synthesize in the same line,
4407 // that later ones do not override the previous ones.
4408 // If we have:
4409 // @synthesize Foo, Bar;
4410 // source ranges for both start at '@', so 'Bar' will end up overriding
4411 // 'Foo' even though the cursor location was at 'Foo'.
4412 if (Data->VisitedObjCPropertyImplDecl)
4413 return CXChildVisit_Break;
4414 Data->VisitedObjCPropertyImplDecl = true;
4415 }
4416 }
4417
4418 if (clang_isExpression(cursor.kind) &&
4419 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 // Avoid having the cursor of an expression replace the declaration cursor
4422 // when the expression source range overlaps the declaration range.
4423 // This can happen for C++ constructor expressions whose range generally
4424 // include the variable declaration, e.g.:
4425 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4426 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4427 D->getLocation() == Data->TokenBeginLoc)
4428 return CXChildVisit_Break;
4429 }
4430 }
4431
4432 // If our current best cursor is the construction of a temporary object,
4433 // don't replace that cursor with a type reference, because we want
4434 // clang_getCursor() to point at the constructor.
4435 if (clang_isExpression(BestCursor->kind) &&
4436 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4437 cursor.kind == CXCursor_TypeRef) {
4438 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4439 // as having the actual point on the type reference.
4440 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4441 return CXChildVisit_Recurse;
4442 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004443
4444 // If we already have an Objective-C superclass reference, don't
4445 // update it further.
4446 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4447 return CXChildVisit_Break;
4448
Guy Benyei11169dd2012-12-18 14:30:41 +00004449 *BestCursor = cursor;
4450 return CXChildVisit_Recurse;
4451}
4452
4453CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004454 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004455 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004457 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004458
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004459 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4461
4462 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4463 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4464
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004465 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 CXFile SearchFile;
4467 unsigned SearchLine, SearchColumn;
4468 CXFile ResultFile;
4469 unsigned ResultLine, ResultColumn;
4470 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4471 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4472 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004473
4474 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4475 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004476 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004477 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 SearchFileName = clang_getFileName(SearchFile);
4479 ResultFileName = clang_getFileName(ResultFile);
4480 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4481 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004482 *Log << llvm::format("(%s:%d:%d) = %s",
4483 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4484 clang_getCString(KindSpelling))
4485 << llvm::format("(%s:%d:%d):%s%s",
4486 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4487 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 clang_disposeString(SearchFileName);
4489 clang_disposeString(ResultFileName);
4490 clang_disposeString(KindSpelling);
4491 clang_disposeString(USR);
4492
4493 CXCursor Definition = clang_getCursorDefinition(Result);
4494 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4495 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4496 CXString DefinitionKindSpelling
4497 = clang_getCursorKindSpelling(Definition.kind);
4498 CXFile DefinitionFile;
4499 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004500 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004501 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004503 *Log << llvm::format(" -> %s(%s:%d:%d)",
4504 clang_getCString(DefinitionKindSpelling),
4505 clang_getCString(DefinitionFileName),
4506 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 clang_disposeString(DefinitionFileName);
4508 clang_disposeString(DefinitionKindSpelling);
4509 }
4510 }
4511
4512 return Result;
4513}
4514
4515CXCursor clang_getNullCursor(void) {
4516 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4517}
4518
4519unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004520 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4521 // can't set consistently. For example, when visiting a DeclStmt we will set
4522 // it but we don't set it on the result of clang_getCursorDefinition for
4523 // a reference of the same declaration.
4524 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4525 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4526 // to provide that kind of info.
4527 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004528 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004529 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004530 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004531
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 return X == Y;
4533}
4534
4535unsigned clang_hashCursor(CXCursor C) {
4536 unsigned Index = 0;
4537 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4538 Index = 1;
4539
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 std::make_pair(C.kind, C.data[Index]));
4542}
4543
4544unsigned clang_isInvalid(enum CXCursorKind K) {
4545 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4546}
4547
4548unsigned clang_isDeclaration(enum CXCursorKind K) {
4549 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4550 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4551}
4552
4553unsigned clang_isReference(enum CXCursorKind K) {
4554 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4555}
4556
4557unsigned clang_isExpression(enum CXCursorKind K) {
4558 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4559}
4560
4561unsigned clang_isStatement(enum CXCursorKind K) {
4562 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4563}
4564
4565unsigned clang_isAttribute(enum CXCursorKind K) {
4566 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4567}
4568
4569unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4570 return K == CXCursor_TranslationUnit;
4571}
4572
4573unsigned clang_isPreprocessing(enum CXCursorKind K) {
4574 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4575}
4576
4577unsigned clang_isUnexposed(enum CXCursorKind K) {
4578 switch (K) {
4579 case CXCursor_UnexposedDecl:
4580 case CXCursor_UnexposedExpr:
4581 case CXCursor_UnexposedStmt:
4582 case CXCursor_UnexposedAttr:
4583 return true;
4584 default:
4585 return false;
4586 }
4587}
4588
4589CXCursorKind clang_getCursorKind(CXCursor C) {
4590 return C.kind;
4591}
4592
4593CXSourceLocation clang_getCursorLocation(CXCursor C) {
4594 if (clang_isReference(C.kind)) {
4595 switch (C.kind) {
4596 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004597 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 = getCursorObjCSuperClassRef(C);
4599 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4600 }
4601
4602 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004603 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 = getCursorObjCProtocolRef(C);
4605 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4606 }
4607
4608 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004609 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 = getCursorObjCClassRef(C);
4611 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4612 }
4613
4614 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004615 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4617 }
4618
4619 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 std::pair<const TemplateDecl *, SourceLocation> P =
4621 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4623 }
4624
4625 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004626 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4628 }
4629
4630 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004631 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4633 }
4634
4635 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004636 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4638 }
4639
4640 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004641 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 if (!BaseSpec)
4643 return clang_getNullLocation();
4644
4645 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4646 return cxloc::translateSourceLocation(getCursorContext(C),
4647 TSInfo->getTypeLoc().getBeginLoc());
4648
4649 return cxloc::translateSourceLocation(getCursorContext(C),
4650 BaseSpec->getLocStart());
4651 }
4652
4653 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004654 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4656 }
4657
4658 case CXCursor_OverloadedDeclRef:
4659 return cxloc::translateSourceLocation(getCursorContext(C),
4660 getCursorOverloadedDeclRef(C).second);
4661
4662 default:
4663 // FIXME: Need a way to enumerate all non-reference cases.
4664 llvm_unreachable("Missed a reference kind");
4665 }
4666 }
4667
4668 if (clang_isExpression(C.kind))
4669 return cxloc::translateSourceLocation(getCursorContext(C),
4670 getLocationFromExpr(getCursorExpr(C)));
4671
4672 if (clang_isStatement(C.kind))
4673 return cxloc::translateSourceLocation(getCursorContext(C),
4674 getCursorStmt(C)->getLocStart());
4675
4676 if (C.kind == CXCursor_PreprocessingDirective) {
4677 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4678 return cxloc::translateSourceLocation(getCursorContext(C), L);
4679 }
4680
4681 if (C.kind == CXCursor_MacroExpansion) {
4682 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004683 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 return cxloc::translateSourceLocation(getCursorContext(C), L);
4685 }
4686
4687 if (C.kind == CXCursor_MacroDefinition) {
4688 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4689 return cxloc::translateSourceLocation(getCursorContext(C), L);
4690 }
4691
4692 if (C.kind == CXCursor_InclusionDirective) {
4693 SourceLocation L
4694 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4695 return cxloc::translateSourceLocation(getCursorContext(C), L);
4696 }
4697
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004698 if (clang_isAttribute(C.kind)) {
4699 SourceLocation L
4700 = cxcursor::getCursorAttr(C)->getLocation();
4701 return cxloc::translateSourceLocation(getCursorContext(C), L);
4702 }
4703
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 if (!clang_isDeclaration(C.kind))
4705 return clang_getNullLocation();
4706
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004707 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 if (!D)
4709 return clang_getNullLocation();
4710
4711 SourceLocation Loc = D->getLocation();
4712 // FIXME: Multiple variables declared in a single declaration
4713 // currently lack the information needed to correctly determine their
4714 // ranges when accounting for the type-specifier. We use context
4715 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4716 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004717 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 if (!cxcursor::isFirstInDeclGroup(C))
4719 Loc = VD->getLocation();
4720 }
4721
4722 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004723 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 Loc = MD->getSelectorStartLoc();
4725
4726 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4727}
4728
4729} // end extern "C"
4730
4731CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4732 assert(TU);
4733
4734 // Guard against an invalid SourceLocation, or we may assert in one
4735 // of the following calls.
4736 if (SLoc.isInvalid())
4737 return clang_getNullCursor();
4738
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004739 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004740
4741 // Translate the given source location to make it point at the beginning of
4742 // the token under the cursor.
4743 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4744 CXXUnit->getASTContext().getLangOpts());
4745
4746 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4747 if (SLoc.isValid()) {
4748 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4749 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4750 /*VisitPreprocessorLast=*/true,
4751 /*VisitIncludedEntities=*/false,
4752 SourceLocation(SLoc));
4753 CursorVis.visitFileRegion();
4754 }
4755
4756 return Result;
4757}
4758
4759static SourceRange getRawCursorExtent(CXCursor C) {
4760 if (clang_isReference(C.kind)) {
4761 switch (C.kind) {
4762 case CXCursor_ObjCSuperClassRef:
4763 return getCursorObjCSuperClassRef(C).second;
4764
4765 case CXCursor_ObjCProtocolRef:
4766 return getCursorObjCProtocolRef(C).second;
4767
4768 case CXCursor_ObjCClassRef:
4769 return getCursorObjCClassRef(C).second;
4770
4771 case CXCursor_TypeRef:
4772 return getCursorTypeRef(C).second;
4773
4774 case CXCursor_TemplateRef:
4775 return getCursorTemplateRef(C).second;
4776
4777 case CXCursor_NamespaceRef:
4778 return getCursorNamespaceRef(C).second;
4779
4780 case CXCursor_MemberRef:
4781 return getCursorMemberRef(C).second;
4782
4783 case CXCursor_CXXBaseSpecifier:
4784 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4785
4786 case CXCursor_LabelRef:
4787 return getCursorLabelRef(C).second;
4788
4789 case CXCursor_OverloadedDeclRef:
4790 return getCursorOverloadedDeclRef(C).second;
4791
4792 case CXCursor_VariableRef:
4793 return getCursorVariableRef(C).second;
4794
4795 default:
4796 // FIXME: Need a way to enumerate all non-reference cases.
4797 llvm_unreachable("Missed a reference kind");
4798 }
4799 }
4800
4801 if (clang_isExpression(C.kind))
4802 return getCursorExpr(C)->getSourceRange();
4803
4804 if (clang_isStatement(C.kind))
4805 return getCursorStmt(C)->getSourceRange();
4806
4807 if (clang_isAttribute(C.kind))
4808 return getCursorAttr(C)->getRange();
4809
4810 if (C.kind == CXCursor_PreprocessingDirective)
4811 return cxcursor::getCursorPreprocessingDirective(C);
4812
4813 if (C.kind == CXCursor_MacroExpansion) {
4814 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004815 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 return TU->mapRangeFromPreamble(Range);
4817 }
4818
4819 if (C.kind == CXCursor_MacroDefinition) {
4820 ASTUnit *TU = getCursorASTUnit(C);
4821 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4822 return TU->mapRangeFromPreamble(Range);
4823 }
4824
4825 if (C.kind == CXCursor_InclusionDirective) {
4826 ASTUnit *TU = getCursorASTUnit(C);
4827 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4828 return TU->mapRangeFromPreamble(Range);
4829 }
4830
4831 if (C.kind == CXCursor_TranslationUnit) {
4832 ASTUnit *TU = getCursorASTUnit(C);
4833 FileID MainID = TU->getSourceManager().getMainFileID();
4834 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4835 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4836 return SourceRange(Start, End);
4837 }
4838
4839 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004840 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 if (!D)
4842 return SourceRange();
4843
4844 SourceRange R = D->getSourceRange();
4845 // FIXME: Multiple variables declared in a single declaration
4846 // currently lack the information needed to correctly determine their
4847 // ranges when accounting for the type-specifier. We use context
4848 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4849 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 if (!cxcursor::isFirstInDeclGroup(C))
4852 R.setBegin(VD->getLocation());
4853 }
4854 return R;
4855 }
4856 return SourceRange();
4857}
4858
4859/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4860/// the decl-specifier-seq for declarations.
4861static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4862 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 if (!D)
4865 return SourceRange();
4866
4867 SourceRange R = D->getSourceRange();
4868
4869 // Adjust the start of the location for declarations preceded by
4870 // declaration specifiers.
4871 SourceLocation StartLoc;
4872 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4873 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4874 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4877 StartLoc = TI->getTypeLoc().getLocStart();
4878 }
4879
4880 if (StartLoc.isValid() && R.getBegin().isValid() &&
4881 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4882 R.setBegin(StartLoc);
4883
4884 // FIXME: Multiple variables declared in a single declaration
4885 // currently lack the information needed to correctly determine their
4886 // ranges when accounting for the type-specifier. We use context
4887 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4888 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004889 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004890 if (!cxcursor::isFirstInDeclGroup(C))
4891 R.setBegin(VD->getLocation());
4892 }
4893
4894 return R;
4895 }
4896
4897 return getRawCursorExtent(C);
4898}
4899
4900extern "C" {
4901
4902CXSourceRange clang_getCursorExtent(CXCursor C) {
4903 SourceRange R = getRawCursorExtent(C);
4904 if (R.isInvalid())
4905 return clang_getNullRange();
4906
4907 return cxloc::translateSourceRange(getCursorContext(C), R);
4908}
4909
4910CXCursor clang_getCursorReferenced(CXCursor C) {
4911 if (clang_isInvalid(C.kind))
4912 return clang_getNullCursor();
4913
4914 CXTranslationUnit tu = getCursorTU(C);
4915 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 if (!D)
4918 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004921 if (const ObjCPropertyImplDecl *PropImpl =
4922 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4924 return MakeCXCursor(Property, tu);
4925
4926 return C;
4927 }
4928
4929 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004930 const Expr *E = getCursorExpr(C);
4931 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 if (D) {
4933 CXCursor declCursor = MakeCXCursor(D, tu);
4934 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4935 declCursor);
4936 return declCursor;
4937 }
4938
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004939 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 return MakeCursorOverloadedDeclRef(Ovl, tu);
4941
4942 return clang_getNullCursor();
4943 }
4944
4945 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004946 const Stmt *S = getCursorStmt(C);
4947 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 if (LabelDecl *label = Goto->getLabel())
4949 if (LabelStmt *labelS = label->getStmt())
4950 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4951
4952 return clang_getNullCursor();
4953 }
Richard Smith66a81862015-05-04 02:25:31 +00004954
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004956 if (const MacroDefinitionRecord *Def =
4957 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 return MakeMacroDefinitionCursor(Def, tu);
4959 }
4960
4961 if (!clang_isReference(C.kind))
4962 return clang_getNullCursor();
4963
4964 switch (C.kind) {
4965 case CXCursor_ObjCSuperClassRef:
4966 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4967
4968 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004969 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4970 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 return MakeCXCursor(Def, tu);
4972
4973 return MakeCXCursor(Prot, tu);
4974 }
4975
4976 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004977 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4978 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 return MakeCXCursor(Def, tu);
4980
4981 return MakeCXCursor(Class, tu);
4982 }
4983
4984 case CXCursor_TypeRef:
4985 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4986
4987 case CXCursor_TemplateRef:
4988 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4989
4990 case CXCursor_NamespaceRef:
4991 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4992
4993 case CXCursor_MemberRef:
4994 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4995
4996 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004997 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4999 tu ));
5000 }
5001
5002 case CXCursor_LabelRef:
5003 // FIXME: We end up faking the "parent" declaration here because we
5004 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005005 return MakeCXCursor(getCursorLabelRef(C).first,
5006 cxtu::getASTUnit(tu)->getASTContext()
5007 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 tu);
5009
5010 case CXCursor_OverloadedDeclRef:
5011 return C;
5012
5013 case CXCursor_VariableRef:
5014 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5015
5016 default:
5017 // We would prefer to enumerate all non-reference cursor kinds here.
5018 llvm_unreachable("Unhandled reference cursor kind");
5019 }
5020}
5021
5022CXCursor clang_getCursorDefinition(CXCursor C) {
5023 if (clang_isInvalid(C.kind))
5024 return clang_getNullCursor();
5025
5026 CXTranslationUnit TU = getCursorTU(C);
5027
5028 bool WasReference = false;
5029 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5030 C = clang_getCursorReferenced(C);
5031 WasReference = true;
5032 }
5033
5034 if (C.kind == CXCursor_MacroExpansion)
5035 return clang_getCursorReferenced(C);
5036
5037 if (!clang_isDeclaration(C.kind))
5038 return clang_getNullCursor();
5039
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005040 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 if (!D)
5042 return clang_getNullCursor();
5043
5044 switch (D->getKind()) {
5045 // Declaration kinds that don't really separate the notions of
5046 // declaration and definition.
5047 case Decl::Namespace:
5048 case Decl::Typedef:
5049 case Decl::TypeAlias:
5050 case Decl::TypeAliasTemplate:
5051 case Decl::TemplateTypeParm:
5052 case Decl::EnumConstant:
5053 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005054 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 case Decl::IndirectField:
5056 case Decl::ObjCIvar:
5057 case Decl::ObjCAtDefsField:
5058 case Decl::ImplicitParam:
5059 case Decl::ParmVar:
5060 case Decl::NonTypeTemplateParm:
5061 case Decl::TemplateTemplateParm:
5062 case Decl::ObjCCategoryImpl:
5063 case Decl::ObjCImplementation:
5064 case Decl::AccessSpec:
5065 case Decl::LinkageSpec:
5066 case Decl::ObjCPropertyImpl:
5067 case Decl::FileScopeAsm:
5068 case Decl::StaticAssert:
5069 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005070 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 case Decl::Label: // FIXME: Is this right??
5072 case Decl::ClassScopeFunctionSpecialization:
5073 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005074 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005075 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 return C;
5077
5078 // Declaration kinds that don't make any sense here, but are
5079 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005080 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005082 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 break;
5084
5085 // Declaration kinds for which the definition is not resolvable.
5086 case Decl::UnresolvedUsingTypename:
5087 case Decl::UnresolvedUsingValue:
5088 break;
5089
5090 case Decl::UsingDirective:
5091 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5092 TU);
5093
5094 case Decl::NamespaceAlias:
5095 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5096
5097 case Decl::Enum:
5098 case Decl::Record:
5099 case Decl::CXXRecord:
5100 case Decl::ClassTemplateSpecialization:
5101 case Decl::ClassTemplatePartialSpecialization:
5102 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5103 return MakeCXCursor(Def, TU);
5104 return clang_getNullCursor();
5105
5106 case Decl::Function:
5107 case Decl::CXXMethod:
5108 case Decl::CXXConstructor:
5109 case Decl::CXXDestructor:
5110 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005111 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005113 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 return clang_getNullCursor();
5115 }
5116
Larisse Voufo39a1e502013-08-06 01:03:05 +00005117 case Decl::Var:
5118 case Decl::VarTemplateSpecialization:
5119 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005121 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 return MakeCXCursor(Def, TU);
5123 return clang_getNullCursor();
5124 }
5125
5126 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005127 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5129 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5130 return clang_getNullCursor();
5131 }
5132
5133 case Decl::ClassTemplate: {
5134 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5135 ->getDefinition())
5136 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5137 TU);
5138 return clang_getNullCursor();
5139 }
5140
Larisse Voufo39a1e502013-08-06 01:03:05 +00005141 case Decl::VarTemplate: {
5142 if (VarDecl *Def =
5143 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5144 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5145 return clang_getNullCursor();
5146 }
5147
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case Decl::Using:
5149 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5150 D->getLocation(), TU);
5151
5152 case Decl::UsingShadow:
5153 return clang_getCursorDefinition(
5154 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5155 TU));
5156
5157 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005158 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 if (Method->isThisDeclarationADefinition())
5160 return C;
5161
5162 // Dig out the method definition in the associated
5163 // @implementation, if we have it.
5164 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005165 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5167 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5168 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5169 Method->isInstanceMethod()))
5170 if (Def->isThisDeclarationADefinition())
5171 return MakeCXCursor(Def, TU);
5172
5173 return clang_getNullCursor();
5174 }
5175
5176 case Decl::ObjCCategory:
5177 if (ObjCCategoryImplDecl *Impl
5178 = cast<ObjCCategoryDecl>(D)->getImplementation())
5179 return MakeCXCursor(Impl, TU);
5180 return clang_getNullCursor();
5181
5182 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005183 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 return MakeCXCursor(Def, TU);
5185 return clang_getNullCursor();
5186
5187 case Decl::ObjCInterface: {
5188 // There are two notions of a "definition" for an Objective-C
5189 // class: the interface and its implementation. When we resolved a
5190 // reference to an Objective-C class, produce the @interface as
5191 // the definition; when we were provided with the interface,
5192 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005193 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005195 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 return MakeCXCursor(Def, TU);
5197 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5198 return MakeCXCursor(Impl, TU);
5199 return clang_getNullCursor();
5200 }
5201
5202 case Decl::ObjCProperty:
5203 // FIXME: We don't really know where to find the
5204 // ObjCPropertyImplDecls that implement this property.
5205 return clang_getNullCursor();
5206
5207 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005208 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005210 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 return MakeCXCursor(Def, TU);
5212
5213 return clang_getNullCursor();
5214
5215 case Decl::Friend:
5216 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5217 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5218 return clang_getNullCursor();
5219
5220 case Decl::FriendTemplate:
5221 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5222 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5223 return clang_getNullCursor();
5224 }
5225
5226 return clang_getNullCursor();
5227}
5228
5229unsigned clang_isCursorDefinition(CXCursor C) {
5230 if (!clang_isDeclaration(C.kind))
5231 return 0;
5232
5233 return clang_getCursorDefinition(C) == C;
5234}
5235
5236CXCursor clang_getCanonicalCursor(CXCursor C) {
5237 if (!clang_isDeclaration(C.kind))
5238 return C;
5239
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005240 if (const Decl *D = getCursorDecl(C)) {
5241 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5243 return MakeCXCursor(CatD, getCursorTU(C));
5244
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005245 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5246 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 return MakeCXCursor(IFD, getCursorTU(C));
5248
5249 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5250 }
5251
5252 return C;
5253}
5254
5255int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5256 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5257}
5258
5259unsigned clang_getNumOverloadedDecls(CXCursor C) {
5260 if (C.kind != CXCursor_OverloadedDeclRef)
5261 return 0;
5262
5263 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005264 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 return E->getNumDecls();
5266
5267 if (OverloadedTemplateStorage *S
5268 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5269 return S->size();
5270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005271 const Decl *D = Storage.get<const Decl *>();
5272 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 return Using->shadow_size();
5274
5275 return 0;
5276}
5277
5278CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5279 if (cursor.kind != CXCursor_OverloadedDeclRef)
5280 return clang_getNullCursor();
5281
5282 if (index >= clang_getNumOverloadedDecls(cursor))
5283 return clang_getNullCursor();
5284
5285 CXTranslationUnit TU = getCursorTU(cursor);
5286 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005287 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 return MakeCXCursor(E->decls_begin()[index], TU);
5289
5290 if (OverloadedTemplateStorage *S
5291 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5292 return MakeCXCursor(S->begin()[index], TU);
5293
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005294 const Decl *D = Storage.get<const Decl *>();
5295 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 // FIXME: This is, unfortunately, linear time.
5297 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5298 std::advance(Pos, index);
5299 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5300 }
5301
5302 return clang_getNullCursor();
5303}
5304
5305void clang_getDefinitionSpellingAndExtent(CXCursor C,
5306 const char **startBuf,
5307 const char **endBuf,
5308 unsigned *startLine,
5309 unsigned *startColumn,
5310 unsigned *endLine,
5311 unsigned *endColumn) {
5312 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005313 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5315
5316 SourceManager &SM = FD->getASTContext().getSourceManager();
5317 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5318 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5319 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5320 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5321 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5322 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5323}
5324
5325
5326CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5327 unsigned PieceIndex) {
5328 RefNamePieces Pieces;
5329
5330 switch (C.kind) {
5331 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005332 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5334 E->getQualifierLoc().getSourceRange());
5335 break;
5336
5337 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005338 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5340 E->getQualifierLoc().getSourceRange(),
5341 E->getOptionalExplicitTemplateArgs());
5342 break;
5343
5344 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005345 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005347 const Expr *Callee = OCE->getCallee();
5348 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 Callee = ICE->getSubExpr();
5350
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005351 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5353 DRE->getQualifierLoc().getSourceRange());
5354 }
5355 break;
5356
5357 default:
5358 break;
5359 }
5360
5361 if (Pieces.empty()) {
5362 if (PieceIndex == 0)
5363 return clang_getCursorExtent(C);
5364 } else if (PieceIndex < Pieces.size()) {
5365 SourceRange R = Pieces[PieceIndex];
5366 if (R.isValid())
5367 return cxloc::translateSourceRange(getCursorContext(C), R);
5368 }
5369
5370 return clang_getNullRange();
5371}
5372
5373void clang_enableStackTraces(void) {
5374 llvm::sys::PrintStackTraceOnErrorSignal();
5375}
5376
5377void clang_executeOnThread(void (*fn)(void*), void *user_data,
5378 unsigned stack_size) {
5379 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5380}
5381
5382} // end: extern "C"
5383
5384//===----------------------------------------------------------------------===//
5385// Token-based Operations.
5386//===----------------------------------------------------------------------===//
5387
5388/* CXToken layout:
5389 * int_data[0]: a CXTokenKind
5390 * int_data[1]: starting token location
5391 * int_data[2]: token length
5392 * int_data[3]: reserved
5393 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5394 * otherwise unused.
5395 */
5396extern "C" {
5397
5398CXTokenKind clang_getTokenKind(CXToken CXTok) {
5399 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5400}
5401
5402CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5403 switch (clang_getTokenKind(CXTok)) {
5404 case CXToken_Identifier:
5405 case CXToken_Keyword:
5406 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005407 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 ->getNameStart());
5409
5410 case CXToken_Literal: {
5411 // We have stashed the starting pointer in the ptr_data field. Use it.
5412 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005413 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 }
5415
5416 case CXToken_Punctuation:
5417 case CXToken_Comment:
5418 break;
5419 }
5420
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005421 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005422 LOG_BAD_TU(TU);
5423 return cxstring::createEmpty();
5424 }
5425
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 // We have to find the starting buffer pointer the hard way, by
5427 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005428 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005430 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005431
5432 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5433 std::pair<FileID, unsigned> LocInfo
5434 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5435 bool Invalid = false;
5436 StringRef Buffer
5437 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5438 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005439 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005440
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005441 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005442}
5443
5444CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005445 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005446 LOG_BAD_TU(TU);
5447 return clang_getNullLocation();
5448 }
5449
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005450 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 if (!CXXUnit)
5452 return clang_getNullLocation();
5453
5454 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5455 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5456}
5457
5458CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005459 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005460 LOG_BAD_TU(TU);
5461 return clang_getNullRange();
5462 }
5463
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005464 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (!CXXUnit)
5466 return clang_getNullRange();
5467
5468 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5469 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5470}
5471
5472static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5473 SmallVectorImpl<CXToken> &CXTokens) {
5474 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5475 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005476 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005478 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005479
5480 // Cannot tokenize across files.
5481 if (BeginLocInfo.first != EndLocInfo.first)
5482 return;
5483
5484 // Create a lexer
5485 bool Invalid = false;
5486 StringRef Buffer
5487 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5488 if (Invalid)
5489 return;
5490
5491 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5492 CXXUnit->getASTContext().getLangOpts(),
5493 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5494 Lex.SetCommentRetentionState(true);
5495
5496 // Lex tokens until we hit the end of the range.
5497 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5498 Token Tok;
5499 bool previousWasAt = false;
5500 do {
5501 // Lex the next token
5502 Lex.LexFromRawLexer(Tok);
5503 if (Tok.is(tok::eof))
5504 break;
5505
5506 // Initialize the CXToken.
5507 CXToken CXTok;
5508
5509 // - Common fields
5510 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5511 CXTok.int_data[2] = Tok.getLength();
5512 CXTok.int_data[3] = 0;
5513
5514 // - Kind-specific fields
5515 if (Tok.isLiteral()) {
5516 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005517 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 } else if (Tok.is(tok::raw_identifier)) {
5519 // Lookup the identifier to determine whether we have a keyword.
5520 IdentifierInfo *II
5521 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5522
5523 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5524 CXTok.int_data[0] = CXToken_Keyword;
5525 }
5526 else {
5527 CXTok.int_data[0] = Tok.is(tok::identifier)
5528 ? CXToken_Identifier
5529 : CXToken_Keyword;
5530 }
5531 CXTok.ptr_data = II;
5532 } else if (Tok.is(tok::comment)) {
5533 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005534 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 } else {
5536 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005537 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 }
5539 CXTokens.push_back(CXTok);
5540 previousWasAt = Tok.is(tok::at);
5541 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5542}
5543
5544void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5545 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005546 LOG_FUNC_SECTION {
5547 *Log << TU << ' ' << Range;
5548 }
5549
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005551 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 if (NumTokens)
5553 *NumTokens = 0;
5554
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005555 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005556 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005557 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005558 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005559
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005560 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 if (!CXXUnit || !Tokens || !NumTokens)
5562 return;
5563
5564 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5565
5566 SourceRange R = cxloc::translateCXSourceRange(Range);
5567 if (R.isInvalid())
5568 return;
5569
5570 SmallVector<CXToken, 32> CXTokens;
5571 getTokens(CXXUnit, R, CXTokens);
5572
5573 if (CXTokens.empty())
5574 return;
5575
5576 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5577 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5578 *NumTokens = CXTokens.size();
5579}
5580
5581void clang_disposeTokens(CXTranslationUnit TU,
5582 CXToken *Tokens, unsigned NumTokens) {
5583 free(Tokens);
5584}
5585
5586} // end: extern "C"
5587
5588//===----------------------------------------------------------------------===//
5589// Token annotation APIs.
5590//===----------------------------------------------------------------------===//
5591
Guy Benyei11169dd2012-12-18 14:30:41 +00005592static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5593 CXCursor parent,
5594 CXClientData client_data);
5595static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5596 CXClientData client_data);
5597
5598namespace {
5599class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 CXToken *Tokens;
5601 CXCursor *Cursors;
5602 unsigned NumTokens;
5603 unsigned TokIdx;
5604 unsigned PreprocessingTokIdx;
5605 CursorVisitor AnnotateVis;
5606 SourceManager &SrcMgr;
5607 bool HasContextSensitiveKeywords;
5608
5609 struct PostChildrenInfo {
5610 CXCursor Cursor;
5611 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005612 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 unsigned BeforeChildrenTokenIdx;
5614 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005615 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005616
5617 CXToken &getTok(unsigned Idx) {
5618 assert(Idx < NumTokens);
5619 return Tokens[Idx];
5620 }
5621 const CXToken &getTok(unsigned Idx) const {
5622 assert(Idx < NumTokens);
5623 return Tokens[Idx];
5624 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 bool MoreTokens() const { return TokIdx < NumTokens; }
5626 unsigned NextToken() const { return TokIdx; }
5627 void AdvanceToken() { ++TokIdx; }
5628 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005629 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 }
5631 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005632 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 }
5634 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005635 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 }
5637
5638 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005639 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 SourceRange);
5641
5642public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005643 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005644 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005645 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005647 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 AnnotateTokensVisitor, this,
5649 /*VisitPreprocessorLast=*/true,
5650 /*VisitIncludedEntities=*/false,
5651 RegionOfInterest,
5652 /*VisitDeclsOnly=*/false,
5653 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005654 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 HasContextSensitiveKeywords(false) { }
5656
5657 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5658 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5659 bool postVisitChildren(CXCursor cursor);
5660 void AnnotateTokens();
5661
5662 /// \brief Determine whether the annotator saw any cursors that have
5663 /// context-sensitive keywords.
5664 bool hasContextSensitiveKeywords() const {
5665 return HasContextSensitiveKeywords;
5666 }
5667
5668 ~AnnotateTokensWorker() {
5669 assert(PostChildrenInfos.empty());
5670 }
5671};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005672}
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
5674void AnnotateTokensWorker::AnnotateTokens() {
5675 // Walk the AST within the region of interest, annotating tokens
5676 // along the way.
5677 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678}
Guy Benyei11169dd2012-12-18 14:30:41 +00005679
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680static inline void updateCursorAnnotation(CXCursor &Cursor,
5681 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005682 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005684 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005685}
5686
5687/// \brief It annotates and advances tokens with a cursor until the comparison
5688//// between the cursor location and the source range is the same as
5689/// \arg compResult.
5690///
5691/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5692/// Pass RangeOverlap to annotate tokens inside a range.
5693void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5694 RangeComparisonResult compResult,
5695 SourceRange range) {
5696 while (MoreTokens()) {
5697 const unsigned I = NextToken();
5698 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005699 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5700 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005701
5702 SourceLocation TokLoc = GetTokenLoc(I);
5703 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005704 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 AdvanceToken();
5706 continue;
5707 }
5708 break;
5709 }
5710}
5711
5712/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005713/// \returns true if it advanced beyond all macro tokens, false otherwise.
5714bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 CXCursor updateC,
5716 RangeComparisonResult compResult,
5717 SourceRange range) {
5718 assert(MoreTokens());
5719 assert(isFunctionMacroToken(NextToken()) &&
5720 "Should be called only for macro arg tokens");
5721
5722 // This works differently than annotateAndAdvanceTokens; because expanded
5723 // macro arguments can have arbitrary translation-unit source order, we do not
5724 // advance the token index one by one until a token fails the range test.
5725 // We only advance once past all of the macro arg tokens if all of them
5726 // pass the range test. If one of them fails we keep the token index pointing
5727 // at the start of the macro arg tokens so that the failing token will be
5728 // annotated by a subsequent annotation try.
5729
5730 bool atLeastOneCompFail = false;
5731
5732 unsigned I = NextToken();
5733 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5734 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5735 if (TokLoc.isFileID())
5736 continue; // not macro arg token, it's parens or comma.
5737 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5738 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5739 Cursors[I] = updateC;
5740 } else
5741 atLeastOneCompFail = true;
5742 }
5743
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005744 if (atLeastOneCompFail)
5745 return false;
5746
5747 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5748 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005749}
5750
5751enum CXChildVisitResult
5752AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 SourceRange cursorRange = getRawCursorExtent(cursor);
5754 if (cursorRange.isInvalid())
5755 return CXChildVisit_Recurse;
5756
5757 if (!HasContextSensitiveKeywords) {
5758 // Objective-C properties can have context-sensitive keywords.
5759 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5762 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5763 }
5764 // Objective-C methods can have context-sensitive keywords.
5765 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5766 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005767 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5769 if (Method->getObjCDeclQualifier())
5770 HasContextSensitiveKeywords = true;
5771 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005772 for (const auto *P : Method->params()) {
5773 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 HasContextSensitiveKeywords = true;
5775 break;
5776 }
5777 }
5778 }
5779 }
5780 }
5781 // C++ methods can have context-sensitive keywords.
5782 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005783 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5785 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5786 HasContextSensitiveKeywords = true;
5787 }
5788 }
5789 // C++ classes can have context-sensitive keywords.
5790 else if (cursor.kind == CXCursor_StructDecl ||
5791 cursor.kind == CXCursor_ClassDecl ||
5792 cursor.kind == CXCursor_ClassTemplate ||
5793 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005794 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 if (D->hasAttr<FinalAttr>())
5796 HasContextSensitiveKeywords = true;
5797 }
5798 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005799
5800 // Don't override a property annotation with its getter/setter method.
5801 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5802 parent.kind == CXCursor_ObjCPropertyDecl)
5803 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005804
5805 if (clang_isPreprocessing(cursor.kind)) {
5806 // Items in the preprocessing record are kept separate from items in
5807 // declarations, so we keep a separate token index.
5808 unsigned SavedTokIdx = TokIdx;
5809 TokIdx = PreprocessingTokIdx;
5810
5811 // Skip tokens up until we catch up to the beginning of the preprocessing
5812 // entry.
5813 while (MoreTokens()) {
5814 const unsigned I = NextToken();
5815 SourceLocation TokLoc = GetTokenLoc(I);
5816 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5817 case RangeBefore:
5818 AdvanceToken();
5819 continue;
5820 case RangeAfter:
5821 case RangeOverlap:
5822 break;
5823 }
5824 break;
5825 }
5826
5827 // Look at all of the tokens within this range.
5828 while (MoreTokens()) {
5829 const unsigned I = NextToken();
5830 SourceLocation TokLoc = GetTokenLoc(I);
5831 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5832 case RangeBefore:
5833 llvm_unreachable("Infeasible");
5834 case RangeAfter:
5835 break;
5836 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005837 // For macro expansions, just note where the beginning of the macro
5838 // expansion occurs.
5839 if (cursor.kind == CXCursor_MacroExpansion) {
5840 if (TokLoc == cursorRange.getBegin())
5841 Cursors[I] = cursor;
5842 AdvanceToken();
5843 break;
5844 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005845 // We may have already annotated macro names inside macro definitions.
5846 if (Cursors[I].kind != CXCursor_MacroExpansion)
5847 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 continue;
5850 }
5851 break;
5852 }
5853
5854 // Save the preprocessing token index; restore the non-preprocessing
5855 // token index.
5856 PreprocessingTokIdx = TokIdx;
5857 TokIdx = SavedTokIdx;
5858 return CXChildVisit_Recurse;
5859 }
5860
5861 if (cursorRange.isInvalid())
5862 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005863
5864 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005866 const enum CXCursorKind K = clang_getCursorKind(parent);
5867 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005868 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5869 // Attributes are annotated out-of-order, skip tokens until we reach it.
5870 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005871 ? clang_getNullCursor() : parent;
5872
5873 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5874
5875 // Avoid having the cursor of an expression "overwrite" the annotation of the
5876 // variable declaration that it belongs to.
5877 // This can happen for C++ constructor expressions whose range generally
5878 // include the variable declaration, e.g.:
5879 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005880 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005881 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005882 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 const unsigned I = NextToken();
5884 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5885 E->getLocStart() == D->getLocation() &&
5886 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005887 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 AdvanceToken();
5889 }
5890 }
5891 }
5892
5893 // Before recursing into the children keep some state that we are going
5894 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5895 // extra work after the child nodes are visited.
5896 // Note that we don't call VisitChildren here to avoid traversing statements
5897 // code-recursively which can blow the stack.
5898
5899 PostChildrenInfo Info;
5900 Info.Cursor = cursor;
5901 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005902 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005903 Info.BeforeChildrenTokenIdx = NextToken();
5904 PostChildrenInfos.push_back(Info);
5905
5906 return CXChildVisit_Recurse;
5907}
5908
5909bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5910 if (PostChildrenInfos.empty())
5911 return false;
5912 const PostChildrenInfo &Info = PostChildrenInfos.back();
5913 if (!clang_equalCursors(Info.Cursor, cursor))
5914 return false;
5915
5916 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5917 const unsigned AfterChildren = NextToken();
5918 SourceRange cursorRange = Info.CursorRange;
5919
5920 // Scan the tokens that are at the end of the cursor, but are not captured
5921 // but the child cursors.
5922 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5923
5924 // Scan the tokens that are at the beginning of the cursor, but are not
5925 // capture by the child cursors.
5926 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5927 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5928 break;
5929
5930 Cursors[I] = cursor;
5931 }
5932
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005933 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5934 // encountered the attribute cursor.
5935 if (clang_isAttribute(cursor.kind))
5936 TokIdx = Info.BeforeReachingCursorIdx;
5937
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 PostChildrenInfos.pop_back();
5939 return false;
5940}
5941
5942static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5943 CXCursor parent,
5944 CXClientData client_data) {
5945 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5946}
5947
5948static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5949 CXClientData client_data) {
5950 return static_cast<AnnotateTokensWorker*>(client_data)->
5951 postVisitChildren(cursor);
5952}
5953
5954namespace {
5955
5956/// \brief Uses the macro expansions in the preprocessing record to find
5957/// and mark tokens that are macro arguments. This info is used by the
5958/// AnnotateTokensWorker.
5959class MarkMacroArgTokensVisitor {
5960 SourceManager &SM;
5961 CXToken *Tokens;
5962 unsigned NumTokens;
5963 unsigned CurIdx;
5964
5965public:
5966 MarkMacroArgTokensVisitor(SourceManager &SM,
5967 CXToken *tokens, unsigned numTokens)
5968 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5969
5970 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5971 if (cursor.kind != CXCursor_MacroExpansion)
5972 return CXChildVisit_Continue;
5973
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005974 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005975 if (macroRange.getBegin() == macroRange.getEnd())
5976 return CXChildVisit_Continue; // it's not a function macro.
5977
5978 for (; CurIdx < NumTokens; ++CurIdx) {
5979 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5980 macroRange.getBegin()))
5981 break;
5982 }
5983
5984 if (CurIdx == NumTokens)
5985 return CXChildVisit_Break;
5986
5987 for (; CurIdx < NumTokens; ++CurIdx) {
5988 SourceLocation tokLoc = getTokenLoc(CurIdx);
5989 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5990 break;
5991
5992 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5993 }
5994
5995 if (CurIdx == NumTokens)
5996 return CXChildVisit_Break;
5997
5998 return CXChildVisit_Continue;
5999 }
6000
6001private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006002 CXToken &getTok(unsigned Idx) {
6003 assert(Idx < NumTokens);
6004 return Tokens[Idx];
6005 }
6006 const CXToken &getTok(unsigned Idx) const {
6007 assert(Idx < NumTokens);
6008 return Tokens[Idx];
6009 }
6010
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006012 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 }
6014
6015 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6016 // The third field is reserved and currently not used. Use it here
6017 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006018 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 }
6020};
6021
6022} // end anonymous namespace
6023
6024static CXChildVisitResult
6025MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6026 CXClientData client_data) {
6027 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6028 parent);
6029}
6030
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006031/// \brief Used by \c annotatePreprocessorTokens.
6032/// \returns true if lexing was finished, false otherwise.
6033static bool lexNext(Lexer &Lex, Token &Tok,
6034 unsigned &NextIdx, unsigned NumTokens) {
6035 if (NextIdx >= NumTokens)
6036 return true;
6037
6038 ++NextIdx;
6039 Lex.LexFromRawLexer(Tok);
6040 if (Tok.is(tok::eof))
6041 return true;
6042
6043 return false;
6044}
6045
Guy Benyei11169dd2012-12-18 14:30:41 +00006046static void annotatePreprocessorTokens(CXTranslationUnit TU,
6047 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006048 CXCursor *Cursors,
6049 CXToken *Tokens,
6050 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006051 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006052
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006053 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006054 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6055 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006056 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006057 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006058 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006059
6060 if (BeginLocInfo.first != EndLocInfo.first)
6061 return;
6062
6063 StringRef Buffer;
6064 bool Invalid = false;
6065 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6066 if (Buffer.empty() || Invalid)
6067 return;
6068
6069 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6070 CXXUnit->getASTContext().getLangOpts(),
6071 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6072 Buffer.end());
6073 Lex.SetCommentRetentionState(true);
6074
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006075 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006076 // Lex tokens in raw mode until we hit the end of the range, to avoid
6077 // entering #includes or expanding macros.
6078 while (true) {
6079 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006080 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6081 break;
6082 unsigned TokIdx = NextIdx-1;
6083 assert(Tok.getLocation() ==
6084 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006085
6086 reprocess:
6087 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006088 // We have found a preprocessing directive. Annotate the tokens
6089 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 //
6091 // FIXME: Some simple tests here could identify macro definitions and
6092 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006093
6094 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006095 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6096 break;
6097
Craig Topper69186e72014-06-08 08:38:04 +00006098 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006099 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006100 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6101 break;
6102
6103 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006104 IdentifierInfo &II =
6105 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006106 SourceLocation MappedTokLoc =
6107 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6108 MI = getMacroInfo(II, MappedTokLoc, TU);
6109 }
6110 }
6111
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006112 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006114 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6115 finished = true;
6116 break;
6117 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006118 // If we are in a macro definition, check if the token was ever a
6119 // macro name and annotate it if that's the case.
6120 if (MI) {
6121 SourceLocation SaveLoc = Tok.getLocation();
6122 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006123 MacroDefinitionRecord *MacroDef =
6124 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006125 Tok.setLocation(SaveLoc);
6126 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006127 Cursors[NextIdx - 1] =
6128 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006129 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006130 } while (!Tok.isAtStartOfLine());
6131
6132 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6133 assert(TokIdx <= LastIdx);
6134 SourceLocation EndLoc =
6135 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6136 CXCursor Cursor =
6137 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6138
6139 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006140 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006141
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006142 if (finished)
6143 break;
6144 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 }
6147}
6148
6149// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006150static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6151 CXToken *Tokens, unsigned NumTokens,
6152 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006153 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6155 setThreadBackgroundPriority();
6156
6157 // Determine the region of interest, which contains all of the tokens.
6158 SourceRange RegionOfInterest;
6159 RegionOfInterest.setBegin(
6160 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6161 RegionOfInterest.setEnd(
6162 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6163 Tokens[NumTokens-1])));
6164
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 // Relex the tokens within the source range to look for preprocessing
6166 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006167 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006168
6169 // If begin location points inside a macro argument, set it to the expansion
6170 // location so we can have the full context when annotating semantically.
6171 {
6172 SourceManager &SM = CXXUnit->getSourceManager();
6173 SourceLocation Loc =
6174 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6175 if (Loc.isMacroID())
6176 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6177 }
6178
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6180 // Search and mark tokens that are macro argument expansions.
6181 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6182 Tokens, NumTokens);
6183 CursorVisitor MacroArgMarker(TU,
6184 MarkMacroArgTokensVisitorDelegate, &Visitor,
6185 /*VisitPreprocessorLast=*/true,
6186 /*VisitIncludedEntities=*/false,
6187 RegionOfInterest);
6188 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6189 }
6190
6191 // Annotate all of the source locations in the region of interest that map to
6192 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006193 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006194
6195 // FIXME: We use a ridiculous stack size here because the data-recursion
6196 // algorithm uses a large stack frame than the non-data recursive version,
6197 // and AnnotationTokensWorker currently transforms the data-recursion
6198 // algorithm back into a traditional recursion by explicitly calling
6199 // VisitChildren(). We will need to remove this explicit recursive call.
6200 W.AnnotateTokens();
6201
6202 // If we ran into any entities that involve context-sensitive keywords,
6203 // take another pass through the tokens to mark them as such.
6204 if (W.hasContextSensitiveKeywords()) {
6205 for (unsigned I = 0; I != NumTokens; ++I) {
6206 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6207 continue;
6208
6209 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6210 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006211 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006212 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6213 if (Property->getPropertyAttributesAsWritten() != 0 &&
6214 llvm::StringSwitch<bool>(II->getName())
6215 .Case("readonly", true)
6216 .Case("assign", true)
6217 .Case("unsafe_unretained", true)
6218 .Case("readwrite", true)
6219 .Case("retain", true)
6220 .Case("copy", true)
6221 .Case("nonatomic", true)
6222 .Case("atomic", true)
6223 .Case("getter", true)
6224 .Case("setter", true)
6225 .Case("strong", true)
6226 .Case("weak", true)
6227 .Default(false))
6228 Tokens[I].int_data[0] = CXToken_Keyword;
6229 }
6230 continue;
6231 }
6232
6233 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6234 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6235 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6236 if (llvm::StringSwitch<bool>(II->getName())
6237 .Case("in", true)
6238 .Case("out", true)
6239 .Case("inout", true)
6240 .Case("oneway", true)
6241 .Case("bycopy", true)
6242 .Case("byref", true)
6243 .Default(false))
6244 Tokens[I].int_data[0] = CXToken_Keyword;
6245 continue;
6246 }
6247
6248 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6249 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6250 Tokens[I].int_data[0] = CXToken_Keyword;
6251 continue;
6252 }
6253 }
6254 }
6255}
6256
6257extern "C" {
6258
6259void clang_annotateTokens(CXTranslationUnit TU,
6260 CXToken *Tokens, unsigned NumTokens,
6261 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006262 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006263 LOG_BAD_TU(TU);
6264 return;
6265 }
6266 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006267 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006268 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006269 }
6270
6271 LOG_FUNC_SECTION {
6272 *Log << TU << ' ';
6273 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6274 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6275 *Log << clang_getRange(bloc, eloc);
6276 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
6278 // Any token we don't specifically annotate will have a NULL cursor.
6279 CXCursor C = clang_getNullCursor();
6280 for (unsigned I = 0; I != NumTokens; ++I)
6281 Cursors[I] = C;
6282
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006283 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 if (!CXXUnit)
6285 return;
6286
6287 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006288
6289 auto AnnotateTokensImpl = [=]() {
6290 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6291 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006292 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006293 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6295 }
6296}
6297
6298} // end: extern "C"
6299
6300//===----------------------------------------------------------------------===//
6301// Operations for querying linkage of a cursor.
6302//===----------------------------------------------------------------------===//
6303
6304extern "C" {
6305CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6306 if (!clang_isDeclaration(cursor.kind))
6307 return CXLinkage_Invalid;
6308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006309 const Decl *D = cxcursor::getCursorDecl(cursor);
6310 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006311 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006312 case NoLinkage:
6313 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006314 case InternalLinkage: return CXLinkage_Internal;
6315 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6316 case ExternalLinkage: return CXLinkage_External;
6317 };
6318
6319 return CXLinkage_Invalid;
6320}
6321} // end: extern "C"
6322
6323//===----------------------------------------------------------------------===//
6324// Operations for querying language of a cursor.
6325//===----------------------------------------------------------------------===//
6326
6327static CXLanguageKind getDeclLanguage(const Decl *D) {
6328 if (!D)
6329 return CXLanguage_C;
6330
6331 switch (D->getKind()) {
6332 default:
6333 break;
6334 case Decl::ImplicitParam:
6335 case Decl::ObjCAtDefsField:
6336 case Decl::ObjCCategory:
6337 case Decl::ObjCCategoryImpl:
6338 case Decl::ObjCCompatibleAlias:
6339 case Decl::ObjCImplementation:
6340 case Decl::ObjCInterface:
6341 case Decl::ObjCIvar:
6342 case Decl::ObjCMethod:
6343 case Decl::ObjCProperty:
6344 case Decl::ObjCPropertyImpl:
6345 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006346 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 return CXLanguage_ObjC;
6348 case Decl::CXXConstructor:
6349 case Decl::CXXConversion:
6350 case Decl::CXXDestructor:
6351 case Decl::CXXMethod:
6352 case Decl::CXXRecord:
6353 case Decl::ClassTemplate:
6354 case Decl::ClassTemplatePartialSpecialization:
6355 case Decl::ClassTemplateSpecialization:
6356 case Decl::Friend:
6357 case Decl::FriendTemplate:
6358 case Decl::FunctionTemplate:
6359 case Decl::LinkageSpec:
6360 case Decl::Namespace:
6361 case Decl::NamespaceAlias:
6362 case Decl::NonTypeTemplateParm:
6363 case Decl::StaticAssert:
6364 case Decl::TemplateTemplateParm:
6365 case Decl::TemplateTypeParm:
6366 case Decl::UnresolvedUsingTypename:
6367 case Decl::UnresolvedUsingValue:
6368 case Decl::Using:
6369 case Decl::UsingDirective:
6370 case Decl::UsingShadow:
6371 return CXLanguage_CPlusPlus;
6372 }
6373
6374 return CXLanguage_C;
6375}
6376
6377extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006378
6379static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6380 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6381 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006383 switch (D->getAvailability()) {
6384 case AR_Available:
6385 case AR_NotYetIntroduced:
6386 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006387 return getCursorAvailabilityForDecl(
6388 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006389 return CXAvailability_Available;
6390
6391 case AR_Deprecated:
6392 return CXAvailability_Deprecated;
6393
6394 case AR_Unavailable:
6395 return CXAvailability_NotAvailable;
6396 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006397
6398 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006399}
6400
Guy Benyei11169dd2012-12-18 14:30:41 +00006401enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6402 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006403 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6404 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006405
6406 return CXAvailability_Available;
6407}
6408
6409static CXVersion convertVersion(VersionTuple In) {
6410 CXVersion Out = { -1, -1, -1 };
6411 if (In.empty())
6412 return Out;
6413
6414 Out.Major = In.getMajor();
6415
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006416 Optional<unsigned> Minor = In.getMinor();
6417 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 Out.Minor = *Minor;
6419 else
6420 return Out;
6421
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006422 Optional<unsigned> Subminor = In.getSubminor();
6423 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 Out.Subminor = *Subminor;
6425
6426 return Out;
6427}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006428
6429static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6430 int *always_deprecated,
6431 CXString *deprecated_message,
6432 int *always_unavailable,
6433 CXString *unavailable_message,
6434 CXPlatformAvailability *availability,
6435 int availability_size) {
6436 bool HadAvailAttr = false;
6437 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006438 for (auto A : D->attrs()) {
6439 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006440 HadAvailAttr = true;
6441 if (always_deprecated)
6442 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006443 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006444 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006445 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006446 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006447 continue;
6448 }
6449
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006450 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006451 HadAvailAttr = true;
6452 if (always_unavailable)
6453 *always_unavailable = 1;
6454 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006455 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006456 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6457 }
6458 continue;
6459 }
6460
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006461 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006462 HadAvailAttr = true;
6463 if (N < availability_size) {
6464 availability[N].Platform
6465 = cxstring::createDup(Avail->getPlatform()->getName());
6466 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6467 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6468 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6469 availability[N].Unavailable = Avail->getUnavailable();
6470 availability[N].Message = cxstring::createDup(Avail->getMessage());
6471 }
6472 ++N;
6473 }
6474 }
6475
6476 if (!HadAvailAttr)
6477 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6478 return getCursorPlatformAvailabilityForDecl(
6479 cast<Decl>(EnumConst->getDeclContext()),
6480 always_deprecated,
6481 deprecated_message,
6482 always_unavailable,
6483 unavailable_message,
6484 availability,
6485 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006486
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006487 return N;
6488}
6489
Guy Benyei11169dd2012-12-18 14:30:41 +00006490int clang_getCursorPlatformAvailability(CXCursor cursor,
6491 int *always_deprecated,
6492 CXString *deprecated_message,
6493 int *always_unavailable,
6494 CXString *unavailable_message,
6495 CXPlatformAvailability *availability,
6496 int availability_size) {
6497 if (always_deprecated)
6498 *always_deprecated = 0;
6499 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006500 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 if (always_unavailable)
6502 *always_unavailable = 0;
6503 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006504 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006505
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 if (!clang_isDeclaration(cursor.kind))
6507 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006509 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 if (!D)
6511 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006512
6513 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6514 deprecated_message,
6515 always_unavailable,
6516 unavailable_message,
6517 availability,
6518 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006519}
6520
6521void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6522 clang_disposeString(availability->Platform);
6523 clang_disposeString(availability->Message);
6524}
6525
6526CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6527 if (clang_isDeclaration(cursor.kind))
6528 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6529
6530 return CXLanguage_Invalid;
6531}
6532
6533 /// \brief If the given cursor is the "templated" declaration
6534 /// descibing a class or function template, return the class or
6535 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006536static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006538 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006540 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006541 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6542 return FunTmpl;
6543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006544 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006545 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6546 return ClassTmpl;
6547
6548 return D;
6549}
6550
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006551
6552enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6553 StorageClass sc = SC_None;
6554 const Decl *D = getCursorDecl(C);
6555 if (D) {
6556 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6557 sc = FD->getStorageClass();
6558 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6559 sc = VD->getStorageClass();
6560 } else {
6561 return CX_SC_Invalid;
6562 }
6563 } else {
6564 return CX_SC_Invalid;
6565 }
6566 switch (sc) {
6567 case SC_None:
6568 return CX_SC_None;
6569 case SC_Extern:
6570 return CX_SC_Extern;
6571 case SC_Static:
6572 return CX_SC_Static;
6573 case SC_PrivateExtern:
6574 return CX_SC_PrivateExtern;
6575 case SC_OpenCLWorkGroupLocal:
6576 return CX_SC_OpenCLWorkGroupLocal;
6577 case SC_Auto:
6578 return CX_SC_Auto;
6579 case SC_Register:
6580 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006581 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006582 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006583}
6584
Guy Benyei11169dd2012-12-18 14:30:41 +00006585CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6586 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006587 if (const Decl *D = getCursorDecl(cursor)) {
6588 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 if (!DC)
6590 return clang_getNullCursor();
6591
6592 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6593 getCursorTU(cursor));
6594 }
6595 }
6596
6597 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006598 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006599 return MakeCXCursor(D, getCursorTU(cursor));
6600 }
6601
6602 return clang_getNullCursor();
6603}
6604
6605CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6606 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006607 if (const Decl *D = getCursorDecl(cursor)) {
6608 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 if (!DC)
6610 return clang_getNullCursor();
6611
6612 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6613 getCursorTU(cursor));
6614 }
6615 }
6616
6617 // FIXME: Note that we can't easily compute the lexical context of a
6618 // statement or expression, so we return nothing.
6619 return clang_getNullCursor();
6620}
6621
6622CXFile clang_getIncludedFile(CXCursor cursor) {
6623 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006624 return nullptr;
6625
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006626 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006627 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006628}
6629
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006630unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6631 if (C.kind != CXCursor_ObjCPropertyDecl)
6632 return CXObjCPropertyAttr_noattr;
6633
6634 unsigned Result = CXObjCPropertyAttr_noattr;
6635 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6636 ObjCPropertyDecl::PropertyAttributeKind Attr =
6637 PD->getPropertyAttributesAsWritten();
6638
6639#define SET_CXOBJCPROP_ATTR(A) \
6640 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6641 Result |= CXObjCPropertyAttr_##A
6642 SET_CXOBJCPROP_ATTR(readonly);
6643 SET_CXOBJCPROP_ATTR(getter);
6644 SET_CXOBJCPROP_ATTR(assign);
6645 SET_CXOBJCPROP_ATTR(readwrite);
6646 SET_CXOBJCPROP_ATTR(retain);
6647 SET_CXOBJCPROP_ATTR(copy);
6648 SET_CXOBJCPROP_ATTR(nonatomic);
6649 SET_CXOBJCPROP_ATTR(setter);
6650 SET_CXOBJCPROP_ATTR(atomic);
6651 SET_CXOBJCPROP_ATTR(weak);
6652 SET_CXOBJCPROP_ATTR(strong);
6653 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6654#undef SET_CXOBJCPROP_ATTR
6655
6656 return Result;
6657}
6658
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006659unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6660 if (!clang_isDeclaration(C.kind))
6661 return CXObjCDeclQualifier_None;
6662
6663 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6664 const Decl *D = getCursorDecl(C);
6665 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6666 QT = MD->getObjCDeclQualifier();
6667 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6668 QT = PD->getObjCDeclQualifier();
6669 if (QT == Decl::OBJC_TQ_None)
6670 return CXObjCDeclQualifier_None;
6671
6672 unsigned Result = CXObjCDeclQualifier_None;
6673 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6674 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6675 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6676 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6677 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6678 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6679
6680 return Result;
6681}
6682
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006683unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6684 if (!clang_isDeclaration(C.kind))
6685 return 0;
6686
6687 const Decl *D = getCursorDecl(C);
6688 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6689 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6690 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6691 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6692
6693 return 0;
6694}
6695
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006696unsigned clang_Cursor_isVariadic(CXCursor C) {
6697 if (!clang_isDeclaration(C.kind))
6698 return 0;
6699
6700 const Decl *D = getCursorDecl(C);
6701 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6702 return FD->isVariadic();
6703 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6704 return MD->isVariadic();
6705
6706 return 0;
6707}
6708
Guy Benyei11169dd2012-12-18 14:30:41 +00006709CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6710 if (!clang_isDeclaration(C.kind))
6711 return clang_getNullRange();
6712
6713 const Decl *D = getCursorDecl(C);
6714 ASTContext &Context = getCursorContext(C);
6715 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6716 if (!RC)
6717 return clang_getNullRange();
6718
6719 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6720}
6721
6722CXString clang_Cursor_getRawCommentText(CXCursor C) {
6723 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006724 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006725
6726 const Decl *D = getCursorDecl(C);
6727 ASTContext &Context = getCursorContext(C);
6728 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6729 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6730 StringRef();
6731
6732 // Don't duplicate the string because RawText points directly into source
6733 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006734 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006735}
6736
6737CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6738 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006739 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006740
6741 const Decl *D = getCursorDecl(C);
6742 const ASTContext &Context = getCursorContext(C);
6743 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6744
6745 if (RC) {
6746 StringRef BriefText = RC->getBriefText(Context);
6747
6748 // Don't duplicate the string because RawComment ensures that this memory
6749 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006750 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006751 }
6752
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006753 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006754}
6755
Guy Benyei11169dd2012-12-18 14:30:41 +00006756CXModule clang_Cursor_getModule(CXCursor C) {
6757 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006758 if (const ImportDecl *ImportD =
6759 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006760 return ImportD->getImportedModule();
6761 }
6762
Craig Topper69186e72014-06-08 08:38:04 +00006763 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006764}
6765
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006766CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6767 if (isNotUsableTU(TU)) {
6768 LOG_BAD_TU(TU);
6769 return nullptr;
6770 }
6771 if (!File)
6772 return nullptr;
6773 FileEntry *FE = static_cast<FileEntry *>(File);
6774
6775 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6776 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6777 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6778
Richard Smithfeb54b62014-10-23 02:01:19 +00006779 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006780}
6781
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006782CXFile clang_Module_getASTFile(CXModule CXMod) {
6783 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006784 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006785 Module *Mod = static_cast<Module*>(CXMod);
6786 return const_cast<FileEntry *>(Mod->getASTFile());
6787}
6788
Guy Benyei11169dd2012-12-18 14:30:41 +00006789CXModule clang_Module_getParent(CXModule CXMod) {
6790 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006791 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006792 Module *Mod = static_cast<Module*>(CXMod);
6793 return Mod->Parent;
6794}
6795
6796CXString clang_Module_getName(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->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006801}
6802
6803CXString clang_Module_getFullName(CXModule CXMod) {
6804 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006805 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006807 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006808}
6809
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006810int clang_Module_isSystem(CXModule CXMod) {
6811 if (!CXMod)
6812 return 0;
6813 Module *Mod = static_cast<Module*>(CXMod);
6814 return Mod->IsSystem;
6815}
6816
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006817unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6818 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006819 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006820 LOG_BAD_TU(TU);
6821 return 0;
6822 }
6823 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 return 0;
6825 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006826 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6827 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6828 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006829}
6830
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006831CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6832 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006833 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006834 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006836 }
6837 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006838 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006839 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006840 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006841
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006842 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6843 if (Index < TopHeaders.size())
6844 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006845
Craig Topper69186e72014-06-08 08:38:04 +00006846 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006847}
6848
6849} // end: extern "C"
6850
6851//===----------------------------------------------------------------------===//
6852// C++ AST instrospection.
6853//===----------------------------------------------------------------------===//
6854
6855extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006856unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6857 if (!clang_isDeclaration(C.kind))
6858 return 0;
6859
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006860 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006861 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006862 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006863 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6864}
6865
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006866unsigned clang_CXXMethod_isConst(CXCursor C) {
6867 if (!clang_isDeclaration(C.kind))
6868 return 0;
6869
6870 const Decl *D = cxcursor::getCursorDecl(C);
6871 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006872 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006873 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6874}
6875
Guy Benyei11169dd2012-12-18 14:30:41 +00006876unsigned clang_CXXMethod_isStatic(CXCursor C) {
6877 if (!clang_isDeclaration(C.kind))
6878 return 0;
6879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006880 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006881 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006882 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006883 return (Method && Method->isStatic()) ? 1 : 0;
6884}
6885
6886unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6887 if (!clang_isDeclaration(C.kind))
6888 return 0;
6889
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006890 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006891 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006892 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006893 return (Method && Method->isVirtual()) ? 1 : 0;
6894}
6895} // end: extern "C"
6896
6897//===----------------------------------------------------------------------===//
6898// Attribute introspection.
6899//===----------------------------------------------------------------------===//
6900
6901extern "C" {
6902CXType clang_getIBOutletCollectionType(CXCursor C) {
6903 if (C.kind != CXCursor_IBOutletCollectionAttr)
6904 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6905
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006906 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006907 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6908
6909 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6910}
6911} // end: extern "C"
6912
6913//===----------------------------------------------------------------------===//
6914// Inspecting memory usage.
6915//===----------------------------------------------------------------------===//
6916
6917typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6918
6919static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6920 enum CXTUResourceUsageKind k,
6921 unsigned long amount) {
6922 CXTUResourceUsageEntry entry = { k, amount };
6923 entries.push_back(entry);
6924}
6925
6926extern "C" {
6927
6928const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6929 const char *str = "";
6930 switch (kind) {
6931 case CXTUResourceUsage_AST:
6932 str = "ASTContext: expressions, declarations, and types";
6933 break;
6934 case CXTUResourceUsage_Identifiers:
6935 str = "ASTContext: identifiers";
6936 break;
6937 case CXTUResourceUsage_Selectors:
6938 str = "ASTContext: selectors";
6939 break;
6940 case CXTUResourceUsage_GlobalCompletionResults:
6941 str = "Code completion: cached global results";
6942 break;
6943 case CXTUResourceUsage_SourceManagerContentCache:
6944 str = "SourceManager: content cache allocator";
6945 break;
6946 case CXTUResourceUsage_AST_SideTables:
6947 str = "ASTContext: side tables";
6948 break;
6949 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6950 str = "SourceManager: malloc'ed memory buffers";
6951 break;
6952 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6953 str = "SourceManager: mmap'ed memory buffers";
6954 break;
6955 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6956 str = "ExternalASTSource: malloc'ed memory buffers";
6957 break;
6958 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6959 str = "ExternalASTSource: mmap'ed memory buffers";
6960 break;
6961 case CXTUResourceUsage_Preprocessor:
6962 str = "Preprocessor: malloc'ed memory";
6963 break;
6964 case CXTUResourceUsage_PreprocessingRecord:
6965 str = "Preprocessor: PreprocessingRecord";
6966 break;
6967 case CXTUResourceUsage_SourceManager_DataStructures:
6968 str = "SourceManager: data structures and tables";
6969 break;
6970 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6971 str = "Preprocessor: header search tables";
6972 break;
6973 }
6974 return str;
6975}
6976
6977CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006978 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006979 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006980 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006981 return usage;
6982 }
6983
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006984 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006985 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006986 ASTContext &astContext = astUnit->getASTContext();
6987
6988 // How much memory is used by AST nodes and types?
6989 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6990 (unsigned long) astContext.getASTAllocatedMemory());
6991
6992 // How much memory is used by identifiers?
6993 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6994 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6995
6996 // How much memory is used for selectors?
6997 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6998 (unsigned long) astContext.Selectors.getTotalMemory());
6999
7000 // How much memory is used by ASTContext's side tables?
7001 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7002 (unsigned long) astContext.getSideTableAllocatedMemory());
7003
7004 // How much memory is used for caching global code completion results?
7005 unsigned long completionBytes = 0;
7006 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007007 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007008 completionBytes = completionAllocator->getTotalMemory();
7009 }
7010 createCXTUResourceUsageEntry(*entries,
7011 CXTUResourceUsage_GlobalCompletionResults,
7012 completionBytes);
7013
7014 // How much memory is being used by SourceManager's content cache?
7015 createCXTUResourceUsageEntry(*entries,
7016 CXTUResourceUsage_SourceManagerContentCache,
7017 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7018
7019 // How much memory is being used by the MemoryBuffer's in SourceManager?
7020 const SourceManager::MemoryBufferSizes &srcBufs =
7021 astUnit->getSourceManager().getMemoryBufferSizes();
7022
7023 createCXTUResourceUsageEntry(*entries,
7024 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7025 (unsigned long) srcBufs.malloc_bytes);
7026 createCXTUResourceUsageEntry(*entries,
7027 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7028 (unsigned long) srcBufs.mmap_bytes);
7029 createCXTUResourceUsageEntry(*entries,
7030 CXTUResourceUsage_SourceManager_DataStructures,
7031 (unsigned long) astContext.getSourceManager()
7032 .getDataStructureSizes());
7033
7034 // How much memory is being used by the ExternalASTSource?
7035 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7036 const ExternalASTSource::MemoryBufferSizes &sizes =
7037 esrc->getMemoryBufferSizes();
7038
7039 createCXTUResourceUsageEntry(*entries,
7040 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7041 (unsigned long) sizes.malloc_bytes);
7042 createCXTUResourceUsageEntry(*entries,
7043 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7044 (unsigned long) sizes.mmap_bytes);
7045 }
7046
7047 // How much memory is being used by the Preprocessor?
7048 Preprocessor &pp = astUnit->getPreprocessor();
7049 createCXTUResourceUsageEntry(*entries,
7050 CXTUResourceUsage_Preprocessor,
7051 pp.getTotalMemory());
7052
7053 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7054 createCXTUResourceUsageEntry(*entries,
7055 CXTUResourceUsage_PreprocessingRecord,
7056 pRec->getTotalMemory());
7057 }
7058
7059 createCXTUResourceUsageEntry(*entries,
7060 CXTUResourceUsage_Preprocessor_HeaderSearch,
7061 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007062
Guy Benyei11169dd2012-12-18 14:30:41 +00007063 CXTUResourceUsage usage = { (void*) entries.get(),
7064 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007065 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007066 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007067 return usage;
7068}
7069
7070void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7071 if (usage.data)
7072 delete (MemUsageEntries*) usage.data;
7073}
7074
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007075CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7076 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007077 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007078 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007079
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007080 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007081 LOG_BAD_TU(TU);
7082 return skipped;
7083 }
7084
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007085 if (!file)
7086 return skipped;
7087
7088 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7089 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7090 if (!ppRec)
7091 return skipped;
7092
7093 ASTContext &Ctx = astUnit->getASTContext();
7094 SourceManager &sm = Ctx.getSourceManager();
7095 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7096 FileID wantedFileID = sm.translateFile(fileEntry);
7097
7098 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7099 std::vector<SourceRange> wantedRanges;
7100 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7101 i != ei; ++i) {
7102 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7103 wantedRanges.push_back(*i);
7104 }
7105
7106 skipped->count = wantedRanges.size();
7107 skipped->ranges = new CXSourceRange[skipped->count];
7108 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7109 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7110
7111 return skipped;
7112}
7113
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007114void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7115 if (ranges) {
7116 delete[] ranges->ranges;
7117 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007118 }
7119}
7120
Guy Benyei11169dd2012-12-18 14:30:41 +00007121} // end extern "C"
7122
7123void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7124 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7125 for (unsigned I = 0; I != Usage.numEntries; ++I)
7126 fprintf(stderr, " %s: %lu\n",
7127 clang_getTUResourceUsageName(Usage.entries[I].kind),
7128 Usage.entries[I].amount);
7129
7130 clang_disposeCXTUResourceUsage(Usage);
7131}
7132
7133//===----------------------------------------------------------------------===//
7134// Misc. utility functions.
7135//===----------------------------------------------------------------------===//
7136
7137/// Default to using an 8 MB stack size on "safety" threads.
7138static unsigned SafetyStackThreadSize = 8 << 20;
7139
7140namespace clang {
7141
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007142bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007143 unsigned Size) {
7144 if (!Size)
7145 Size = GetSafetyThreadStackSize();
7146 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007147 return CRC.RunSafelyOnThread(Fn, Size);
7148 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007149}
7150
7151unsigned GetSafetyThreadStackSize() {
7152 return SafetyStackThreadSize;
7153}
7154
7155void SetSafetyThreadStackSize(unsigned Value) {
7156 SafetyStackThreadSize = Value;
7157}
7158
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007159}
Guy Benyei11169dd2012-12-18 14:30:41 +00007160
7161void clang::setThreadBackgroundPriority() {
7162 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7163 return;
7164
Alp Toker1a86ad22014-07-06 06:24:00 +00007165#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007166 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7167#endif
7168}
7169
7170void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7171 if (!Unit)
7172 return;
7173
7174 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7175 DEnd = Unit->stored_diag_end();
7176 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007177 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007178 CXString Msg = clang_formatDiagnostic(&Diag,
7179 clang_defaultDiagnosticDisplayOptions());
7180 fprintf(stderr, "%s\n", clang_getCString(Msg));
7181 clang_disposeString(Msg);
7182 }
7183#ifdef LLVM_ON_WIN32
7184 // On Windows, force a flush, since there may be multiple copies of
7185 // stderr and stdout in the file system, all with different buffers
7186 // but writing to the same device.
7187 fflush(stderr);
7188#endif
7189}
7190
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7192 SourceLocation MacroDefLoc,
7193 CXTranslationUnit TU){
7194 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007195 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007196 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007197 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007198
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007199 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007200 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007201 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007202 if (MD) {
7203 for (MacroDirective::DefInfo
7204 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7205 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7206 return Def.getMacroInfo();
7207 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007208 }
7209
Craig Topper69186e72014-06-08 08:38:04 +00007210 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211}
7212
Richard Smith66a81862015-05-04 02:25:31 +00007213const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007214 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007215 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007216 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217 const IdentifierInfo *II = MacroDef->getName();
7218 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007219 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007220
7221 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7222}
7223
Richard Smith66a81862015-05-04 02:25:31 +00007224MacroDefinitionRecord *
7225cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7226 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007227 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007228 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007229 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007230 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231
7232 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007233 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7235 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007236 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237
7238 // Check that the token is inside the definition and not its argument list.
7239 SourceManager &SM = Unit->getSourceManager();
7240 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007241 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007242 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007243 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007244
7245 Preprocessor &PP = Unit->getPreprocessor();
7246 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7247 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007248 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007249
Alp Toker2d57cea2014-05-17 04:53:25 +00007250 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007252 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007253
7254 // Check that the identifier is not one of the macro arguments.
7255 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007256 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257
Richard Smith20e883e2015-04-29 23:20:19 +00007258 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007259 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007260 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007262 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007263}
7264
Richard Smith66a81862015-05-04 02:25:31 +00007265MacroDefinitionRecord *
7266cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7267 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270
7271 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007272 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007273 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007274 Preprocessor &PP = Unit->getPreprocessor();
7275 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007276 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007277 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7278 Token Tok;
7279 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007280 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007281
7282 return checkForMacroInMacroDefinition(MI, Tok, TU);
7283}
7284
Guy Benyei11169dd2012-12-18 14:30:41 +00007285extern "C" {
7286
7287CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007288 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007289}
7290
7291} // end: extern "C"
7292
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007293Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7294 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007295 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007296 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007297 if (Unit->isMainFileAST())
7298 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007299 return *this;
7300 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007301 } else {
7302 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007303 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007304 return *this;
7305}
7306
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007307Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7308 *this << FE->getName();
7309 return *this;
7310}
7311
7312Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7313 CXString cursorName = clang_getCursorDisplayName(cursor);
7314 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7315 clang_disposeString(cursorName);
7316 return *this;
7317}
7318
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007319Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7320 CXFile File;
7321 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007322 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007323 CXString FileName = clang_getFileName(File);
7324 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7325 clang_disposeString(FileName);
7326 return *this;
7327}
7328
7329Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7330 CXSourceLocation BLoc = clang_getRangeStart(range);
7331 CXSourceLocation ELoc = clang_getRangeEnd(range);
7332
7333 CXFile BFile;
7334 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007335 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007336
7337 CXFile EFile;
7338 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007339 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007340
7341 CXString BFileName = clang_getFileName(BFile);
7342 if (BFile == EFile) {
7343 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7344 BLine, BColumn, ELine, EColumn);
7345 } else {
7346 CXString EFileName = clang_getFileName(EFile);
7347 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7348 BLine, BColumn)
7349 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7350 ELine, EColumn);
7351 clang_disposeString(EFileName);
7352 }
7353 clang_disposeString(BFileName);
7354 return *this;
7355}
7356
7357Logger &cxindex::Logger::operator<<(CXString Str) {
7358 *this << clang_getCString(Str);
7359 return *this;
7360}
7361
7362Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7363 LogOS << Fmt;
7364 return *this;
7365}
7366
Chandler Carruth37ad2582014-06-27 15:14:39 +00007367static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7368
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007369cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007370 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007371
7372 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7373
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007374 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007375 OS << "[libclang:" << Name << ':';
7376
Alp Toker1a86ad22014-07-06 06:24:00 +00007377#ifdef USE_DARWIN_THREADS
7378 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007379 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7380 OS << tid << ':';
7381#endif
7382
7383 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7384 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007385 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007386
7387 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007388 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007389 OS << "--------------------------------------------------\n";
7390 }
7391}