blob: 1fb62d259cd7f1abab9bde3af4973e1d12d98e61 [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);
Alexander Musman3276a272015-03-21 10:12:56 +00002109 for (const auto *E : C->inits()) {
2110 Visitor->AddStmt(E);
2111 }
2112 for (const auto *E : C->updates()) {
2113 Visitor->AddStmt(E);
2114 }
2115 for (const auto *E : C->finals()) {
2116 Visitor->AddStmt(E);
2117 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002118 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002119 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002120}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002121void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2122 VisitOMPClauseList(C);
2123 Visitor->AddStmt(C->getAlignment());
2124}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002125void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2126 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002127 for (auto *E : C->source_exprs()) {
2128 Visitor->AddStmt(E);
2129 }
2130 for (auto *E : C->destination_exprs()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (auto *E : C->assignment_ops()) {
2134 Visitor->AddStmt(E);
2135 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002136}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002137void
2138OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2139 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002140 for (auto *E : C->source_exprs()) {
2141 Visitor->AddStmt(E);
2142 }
2143 for (auto *E : C->destination_exprs()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (auto *E : C->assignment_ops()) {
2147 Visitor->AddStmt(E);
2148 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002149}
Alexey Bataev6125da92014-07-21 11:26:11 +00002150void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2151 VisitOMPClauseList(C);
2152}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002153void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2154 VisitOMPClauseList(C);
2155}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002156}
Alexey Bataev756c1962013-09-24 03:17:45 +00002157
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002158void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2159 unsigned size = WL.size();
2160 OMPClauseEnqueue Visitor(this);
2161 Visitor.Visit(S);
2162 if (size == WL.size())
2163 return;
2164 // Now reverse the entries we just added. This will match the DFS
2165 // ordering performed by the worklist.
2166 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2167 std::reverse(I, E);
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddDecl(B->getBlockDecl());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 EnqueueChildren(E);
2177 AddTypeLoc(E->getTypeSourceInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002180 for (auto &I : llvm::reverse(S->body()))
2181 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002182}
2183void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddStmt(S->getSubStmt());
2186 AddDeclarationNameInfo(S);
2187 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2188 AddNestedNameSpecifierLoc(QualifierLoc);
2189}
2190
2191void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2194 AddDeclarationNameInfo(E);
2195 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2196 AddNestedNameSpecifierLoc(QualifierLoc);
2197 if (!E->isImplicitAccess())
2198 AddStmt(E->getBase());
2199}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 // Enqueue the initializer , if any.
2202 AddStmt(E->getInitializer());
2203 // Enqueue the array size, if any.
2204 AddStmt(E->getArraySize());
2205 // Enqueue the allocated type.
2206 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2207 // Enqueue the placement arguments.
2208 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2209 AddStmt(E->getPlacementArg(I-1));
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2213 AddStmt(CE->getArg(I-1));
2214 AddStmt(CE->getCallee());
2215 AddStmt(CE->getArg(0));
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2218 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // Visit the name of the type being destroyed.
2220 AddTypeLoc(E->getDestroyedTypeInfo());
2221 // Visit the scope type that looks disturbingly like the nested-name-specifier
2222 // but isn't.
2223 AddTypeLoc(E->getScopeTypeInfo());
2224 // Visit the nested-name-specifier.
2225 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2226 AddNestedNameSpecifierLoc(QualifierLoc);
2227 // Visit base expression.
2228 AddStmt(E->getBase());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2231 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddTypeLoc(E->getTypeSourceInfo());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2235 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 EnqueueChildren(E);
2237 AddTypeLoc(E->getTypeSourceInfo());
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueChildren(E);
2241 if (E->isTypeOperand())
2242 AddTypeLoc(E->getTypeOperandSourceInfo());
2243}
2244
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2246 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(E);
2248 AddTypeLoc(E->getTypeSourceInfo());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(E);
2252 if (E->isTypeOperand())
2253 AddTypeLoc(E->getTypeOperandSourceInfo());
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueChildren(S);
2258 AddDecl(S->getExceptionDecl());
2259}
2260
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002261void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002262 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002263 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002264 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002265}
2266
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 if (DR->hasExplicitTemplateArgs()) {
2269 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2270 }
2271 WL.push_back(DeclRefExprParts(DR, Parent));
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2274 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2276 AddDeclarationNameInfo(E);
2277 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 unsigned size = WL.size();
2281 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002282 for (const auto *D : S->decls()) {
2283 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 isFirst = false;
2285 }
2286 if (size == WL.size())
2287 return;
2288 // Now reverse the entries we just added. This will match the DFS
2289 // ordering performed by the worklist.
2290 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2291 std::reverse(I, E);
2292}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 D = E->designators_rbegin(), DEnd = E->designators_rend();
2297 D != DEnd; ++D) {
2298 if (D->isFieldDesignator()) {
2299 if (FieldDecl *Field = D->getField())
2300 AddMemberRef(Field, D->getFieldLoc());
2301 continue;
2302 }
2303 if (D->isArrayDesignator()) {
2304 AddStmt(E->getArrayIndex(*D));
2305 continue;
2306 }
2307 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2308 AddStmt(E->getArrayRangeEnd(*D));
2309 AddStmt(E->getArrayRangeStart(*D));
2310 }
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 EnqueueChildren(E);
2314 AddTypeLoc(E->getTypeInfoAsWritten());
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 AddStmt(FS->getBody());
2318 AddStmt(FS->getInc());
2319 AddStmt(FS->getCond());
2320 AddDecl(FS->getConditionVariable());
2321 AddStmt(FS->getInit());
2322}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2325}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 AddStmt(If->getElse());
2328 AddStmt(If->getThen());
2329 AddStmt(If->getCond());
2330 AddDecl(If->getConditionVariable());
2331}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 // We care about the syntactic form of the initializer list, only.
2334 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2335 IE = Syntactic;
2336 EnqueueChildren(IE);
2337}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 WL.push_back(MemberExprParts(M, Parent));
2340
2341 // If the base of the member access expression is an implicit 'this', don't
2342 // visit it.
2343 // FIXME: If we ever want to show these implicit accesses, this will be
2344 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002345 if (M->isImplicitAccess())
2346 return;
2347
2348 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2349 // real field that that we are interested in.
2350 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2351 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2352 if (FD->isAnonymousStructOrUnion()) {
2353 AddStmt(SubME->getBase());
2354 return;
2355 }
2356 }
2357 }
2358
2359 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002360}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002361void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002362 AddTypeLoc(E->getEncodedTypeSourceInfo());
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 EnqueueChildren(M);
2366 AddTypeLoc(M->getClassReceiverTypeInfo());
2367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 // Visit the components of the offsetof expression.
2370 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2371 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2372 const OffsetOfNode &Node = E->getComponent(I-1);
2373 switch (Node.getKind()) {
2374 case OffsetOfNode::Array:
2375 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2376 break;
2377 case OffsetOfNode::Field:
2378 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2379 break;
2380 case OffsetOfNode::Identifier:
2381 case OffsetOfNode::Base:
2382 continue;
2383 }
2384 }
2385 // Visit the type into which we're computing the offset.
2386 AddTypeLoc(E->getTypeSourceInfo());
2387}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2390 WL.push_back(OverloadExprParts(E, Parent));
2391}
2392void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 EnqueueChildren(E);
2395 if (E->isArgumentType())
2396 AddTypeLoc(E->getArgumentTypeInfo());
2397}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 EnqueueChildren(S);
2400}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 AddStmt(S->getBody());
2403 AddStmt(S->getCond());
2404 AddDecl(S->getConditionVariable());
2405}
2406
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 AddStmt(W->getBody());
2409 AddStmt(W->getCond());
2410 AddDecl(W->getConditionVariable());
2411}
2412
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 for (unsigned I = E->getNumArgs(); I > 0; --I)
2415 AddTypeLoc(E->getArg(I-1));
2416}
2417
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 AddTypeLoc(E->getQueriedTypeSourceInfo());
2420}
2421
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 EnqueueChildren(E);
2424}
2425
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 VisitOverloadExpr(U);
2428 if (!U->isImplicitAccess())
2429 AddStmt(U->getBase());
2430}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 AddStmt(E->getSubExpr());
2433 AddTypeLoc(E->getWrittenTypeInfo());
2434}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 WL.push_back(SizeOfPackExprParts(E, Parent));
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 // If the opaque value has a source expression, just transparently
2440 // visit that. This is useful for (e.g.) pseudo-object expressions.
2441 if (Expr *SourceExpr = E->getSourceExpr())
2442 return Visit(SourceExpr);
2443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 AddStmt(E->getBody());
2446 WL.push_back(LambdaExprParts(E, Parent));
2447}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002448void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 // Treat the expression like its syntactic form.
2450 Visit(E->getSyntacticForm());
2451}
2452
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002453void EnqueueVisitor::VisitOMPExecutableDirective(
2454 const OMPExecutableDirective *D) {
2455 EnqueueChildren(D);
2456 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2457 E = D->clauses().end();
2458 I != E; ++I)
2459 EnqueueChildren(*I);
2460}
2461
Alexander Musman3aaab662014-08-19 11:27:13 +00002462void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2463 VisitOMPExecutableDirective(D);
2464}
2465
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002466void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2467 VisitOMPExecutableDirective(D);
2468}
2469
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002470void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002471 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002472}
2473
Alexey Bataevf29276e2014-06-18 04:14:57 +00002474void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002475 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002476}
2477
Alexander Musmanf82886e2014-09-18 05:12:34 +00002478void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2479 VisitOMPLoopDirective(D);
2480}
2481
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002482void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2483 VisitOMPExecutableDirective(D);
2484}
2485
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002486void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2487 VisitOMPExecutableDirective(D);
2488}
2489
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002490void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2491 VisitOMPExecutableDirective(D);
2492}
2493
Alexander Musman80c22892014-07-17 08:54:58 +00002494void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496}
2497
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002498void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2499 VisitOMPExecutableDirective(D);
2500 AddDeclarationNameInfo(D);
2501}
2502
Alexey Bataev4acb8592014-07-07 13:01:15 +00002503void
2504EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002505 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002506}
2507
Alexander Musmane4e893b2014-09-23 09:33:00 +00002508void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2509 const OMPParallelForSimdDirective *D) {
2510 VisitOMPLoopDirective(D);
2511}
2512
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002513void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2514 const OMPParallelSectionsDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002518void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Alexey Bataev68446b72014-07-18 07:47:19 +00002522void
2523EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525}
2526
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002527void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2528 VisitOMPExecutableDirective(D);
2529}
2530
Alexey Bataev2df347a2014-07-18 10:17:07 +00002531void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2532 VisitOMPExecutableDirective(D);
2533}
2534
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002535void EnqueueVisitor::VisitOMPTaskgroupDirective(
2536 const OMPTaskgroupDirective *D) {
2537 VisitOMPExecutableDirective(D);
2538}
2539
Alexey Bataev6125da92014-07-21 11:26:11 +00002540void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2541 VisitOMPExecutableDirective(D);
2542}
2543
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002544void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2545 VisitOMPExecutableDirective(D);
2546}
2547
Alexey Bataev0162e452014-07-22 10:10:35 +00002548void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2549 VisitOMPExecutableDirective(D);
2550}
2551
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002552void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2553 VisitOMPExecutableDirective(D);
2554}
2555
Michael Wong65f367f2015-07-21 13:44:28 +00002556void EnqueueVisitor::VisitOMPTargetDataDirective(const
2557 OMPTargetDataDirective *D) {
2558 VisitOMPExecutableDirective(D);
2559}
2560
Alexey Bataev13314bf2014-10-09 04:18:56 +00002561void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002565void EnqueueVisitor::VisitOMPCancellationPointDirective(
2566 const OMPCancellationPointDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev80909872015-07-02 11:25:17 +00002570void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002574void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2576}
2577
2578bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2579 if (RegionOfInterest.isValid()) {
2580 SourceRange Range = getRawCursorExtent(C);
2581 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2582 return false;
2583 }
2584 return true;
2585}
2586
2587bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2588 while (!WL.empty()) {
2589 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002590 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002591
2592 // Set the Parent field, then back to its old value once we're done.
2593 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2594
2595 switch (LI.getKind()) {
2596 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002597 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598 if (!D)
2599 continue;
2600
2601 // For now, perform default visitation for Decls.
2602 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2603 cast<DeclVisit>(&LI)->isFirst())))
2604 return true;
2605
2606 continue;
2607 }
2608 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2609 const ASTTemplateArgumentListInfo *ArgList =
2610 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2611 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2612 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2613 Arg != ArgEnd; ++Arg) {
2614 if (VisitTemplateArgumentLoc(*Arg))
2615 return true;
2616 }
2617 continue;
2618 }
2619 case VisitorJob::TypeLocVisitKind: {
2620 // Perform default visitation for TypeLocs.
2621 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2622 return true;
2623 continue;
2624 }
2625 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002626 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002627 if (LabelStmt *stmt = LS->getStmt()) {
2628 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2629 TU))) {
2630 return true;
2631 }
2632 }
2633 continue;
2634 }
2635
2636 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2637 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2638 if (VisitNestedNameSpecifierLoc(V->get()))
2639 return true;
2640 continue;
2641 }
2642
2643 case VisitorJob::DeclarationNameInfoVisitKind: {
2644 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2645 ->get()))
2646 return true;
2647 continue;
2648 }
2649 case VisitorJob::MemberRefVisitKind: {
2650 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2651 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2652 return true;
2653 continue;
2654 }
2655 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002656 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002657 if (!S)
2658 continue;
2659
2660 // Update the current cursor.
2661 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2662 if (!IsInRegionOfInterest(Cursor))
2663 continue;
2664 switch (Visitor(Cursor, Parent, ClientData)) {
2665 case CXChildVisit_Break: return true;
2666 case CXChildVisit_Continue: break;
2667 case CXChildVisit_Recurse:
2668 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002669 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002670 EnqueueWorkList(WL, S);
2671 break;
2672 }
2673 continue;
2674 }
2675 case VisitorJob::MemberExprPartsKind: {
2676 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002677 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002678
2679 // Visit the nested-name-specifier
2680 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2681 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2682 return true;
2683
2684 // Visit the declaration name.
2685 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2686 return true;
2687
2688 // Visit the explicitly-specified template arguments, if any.
2689 if (M->hasExplicitTemplateArgs()) {
2690 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2691 *ArgEnd = Arg + M->getNumTemplateArgs();
2692 Arg != ArgEnd; ++Arg) {
2693 if (VisitTemplateArgumentLoc(*Arg))
2694 return true;
2695 }
2696 }
2697 continue;
2698 }
2699 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002700 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 // Visit nested-name-specifier, if present.
2702 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2703 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2704 return true;
2705 // Visit declaration name.
2706 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2707 return true;
2708 continue;
2709 }
2710 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002711 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002712 // Visit the nested-name-specifier.
2713 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2714 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2715 return true;
2716 // Visit the declaration name.
2717 if (VisitDeclarationNameInfo(O->getNameInfo()))
2718 return true;
2719 // Visit the overloaded declaration reference.
2720 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2721 return true;
2722 continue;
2723 }
2724 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002725 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 NamedDecl *Pack = E->getPack();
2727 if (isa<TemplateTypeParmDecl>(Pack)) {
2728 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2729 E->getPackLoc(), TU)))
2730 return true;
2731
2732 continue;
2733 }
2734
2735 if (isa<TemplateTemplateParmDecl>(Pack)) {
2736 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2737 E->getPackLoc(), TU)))
2738 return true;
2739
2740 continue;
2741 }
2742
2743 // Non-type template parameter packs and function parameter packs are
2744 // treated like DeclRefExpr cursors.
2745 continue;
2746 }
2747
2748 case VisitorJob::LambdaExprPartsKind: {
2749 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002750 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002751 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2752 CEnd = E->explicit_capture_end();
2753 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002754 // FIXME: Lambda init-captures.
2755 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002757
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2759 C->getLocation(),
2760 TU)))
2761 return true;
2762 }
2763
2764 // Visit parameters and return type, if present.
2765 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2766 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2767 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2768 // Visit the whole type.
2769 if (Visit(TL))
2770 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002771 } else if (FunctionProtoTypeLoc Proto =
2772 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 if (E->hasExplicitParameters()) {
2774 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002775 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2776 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 return true;
2778 } else {
2779 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002780 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 return true;
2782 }
2783 }
2784 }
2785 break;
2786 }
2787
2788 case VisitorJob::PostChildrenVisitKind:
2789 if (PostChildrenVisitor(Parent, ClientData))
2790 return true;
2791 break;
2792 }
2793 }
2794 return false;
2795}
2796
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002797bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002798 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 if (!WorkListFreeList.empty()) {
2800 WL = WorkListFreeList.back();
2801 WL->clear();
2802 WorkListFreeList.pop_back();
2803 }
2804 else {
2805 WL = new VisitorWorkList();
2806 WorkListCache.push_back(WL);
2807 }
2808 EnqueueWorkList(*WL, S);
2809 bool result = RunVisitorWorkList(*WL);
2810 WorkListFreeList.push_back(WL);
2811 return result;
2812}
2813
2814namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002815typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002816RefNamePieces
2817buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2818 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2819 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002820 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2821 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2822 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2823
2824 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2825
2826 RefNamePieces Pieces;
2827
2828 if (WantQualifier && QLoc.isValid())
2829 Pieces.push_back(QLoc);
2830
2831 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2832 Pieces.push_back(NI.getLoc());
2833
2834 if (WantTemplateArgs && TemplateArgs)
2835 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2836 TemplateArgs->RAngleLoc));
2837
2838 if (Kind == DeclarationName::CXXOperatorName) {
2839 Pieces.push_back(SourceLocation::getFromRawEncoding(
2840 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2841 Pieces.push_back(SourceLocation::getFromRawEncoding(
2842 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2843 }
2844
2845 if (WantSinglePiece) {
2846 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2847 Pieces.clear();
2848 Pieces.push_back(R);
2849 }
2850
2851 return Pieces;
2852}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002853}
Guy Benyei11169dd2012-12-18 14:30:41 +00002854
2855//===----------------------------------------------------------------------===//
2856// Misc. API hooks.
2857//===----------------------------------------------------------------------===//
2858
Chad Rosier05c71aa2013-03-27 18:28:23 +00002859static void fatal_error_handler(void *user_data, const std::string& reason,
2860 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 // Write the result out to stderr avoiding errs() because raw_ostreams can
2862 // call report_fatal_error.
2863 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2864 ::abort();
2865}
2866
Chandler Carruth66660742014-06-27 16:37:27 +00002867namespace {
2868struct RegisterFatalErrorHandler {
2869 RegisterFatalErrorHandler() {
2870 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2871 }
2872};
2873}
2874
2875static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2876
Guy Benyei11169dd2012-12-18 14:30:41 +00002877extern "C" {
2878CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2879 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 // We use crash recovery to make some of our APIs more reliable, implicitly
2881 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002882 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2883 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002884
Chandler Carruth66660742014-06-27 16:37:27 +00002885 // Look through the managed static to trigger construction of the managed
2886 // static which registers our fatal error handler. This ensures it is only
2887 // registered once.
2888 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002889
Adrian Prantlbc068582015-07-08 01:00:30 +00002890 // Initialize targets for clang module support.
2891 llvm::InitializeAllTargets();
2892 llvm::InitializeAllTargetMCs();
2893 llvm::InitializeAllAsmPrinters();
2894 llvm::InitializeAllAsmParsers();
2895
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002896 CIndexer *CIdxr = new CIndexer();
2897
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 if (excludeDeclarationsFromPCH)
2899 CIdxr->setOnlyLocalDecls();
2900 if (displayDiagnostics)
2901 CIdxr->setDisplayDiagnostics();
2902
2903 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2904 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2905 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2906 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2907 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2908 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2909
2910 return CIdxr;
2911}
2912
2913void clang_disposeIndex(CXIndex CIdx) {
2914 if (CIdx)
2915 delete static_cast<CIndexer *>(CIdx);
2916}
2917
2918void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2919 if (CIdx)
2920 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2921}
2922
2923unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2924 if (CIdx)
2925 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2926 return 0;
2927}
2928
2929void clang_toggleCrashRecovery(unsigned isEnabled) {
2930 if (isEnabled)
2931 llvm::CrashRecoveryContext::Enable();
2932 else
2933 llvm::CrashRecoveryContext::Disable();
2934}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935
Guy Benyei11169dd2012-12-18 14:30:41 +00002936CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2937 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002938 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002939 enum CXErrorCode Result =
2940 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002941 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002942 assert((TU && Result == CXError_Success) ||
2943 (!TU && Result != CXError_Success));
2944 return TU;
2945}
2946
2947enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2948 const char *ast_filename,
2949 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002950 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002951 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002952
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953 if (!CIdx || !ast_filename || !out_TU)
2954 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002955
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002956 LOG_FUNC_SECTION {
2957 *Log << ast_filename;
2958 }
2959
Guy Benyei11169dd2012-12-18 14:30:41 +00002960 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2961 FileSystemOptions FileSystemOpts;
2962
Justin Bognerd512c1e2014-10-15 00:33:06 +00002963 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2964 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002965 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002966 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
2967 FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002968 /*CaptureDiagnostics=*/true,
2969 /*AllowPCHWithCompilerErrors=*/true,
2970 /*UserFilesAreVolatile=*/true);
2971 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002972 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973}
2974
2975unsigned clang_defaultEditingTranslationUnitOptions() {
2976 return CXTranslationUnit_PrecompiledPreamble |
2977 CXTranslationUnit_CacheCompletionResults;
2978}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979
Guy Benyei11169dd2012-12-18 14:30:41 +00002980CXTranslationUnit
2981clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2982 const char *source_filename,
2983 int num_command_line_args,
2984 const char * const *command_line_args,
2985 unsigned num_unsaved_files,
2986 struct CXUnsavedFile *unsaved_files) {
2987 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2988 return clang_parseTranslationUnit(CIdx, source_filename,
2989 command_line_args, num_command_line_args,
2990 unsaved_files, num_unsaved_files,
2991 Options);
2992}
2993
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00002994static CXErrorCode
2995clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
2996 const char *const *command_line_args,
2997 int num_command_line_args,
2998 ArrayRef<CXUnsavedFile> unsaved_files,
2999 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003000 // Set up the initial return values.
3001 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003002 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003003
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003005 if (!CIdx || !out_TU)
3006 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003007
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3009
3010 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3011 setThreadBackgroundPriority();
3012
3013 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3014 // FIXME: Add a flag for modules.
3015 TranslationUnitKind TUKind
3016 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003017 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 = options & CXTranslationUnit_CacheCompletionResults;
3019 bool IncludeBriefCommentsInCodeCompletion
3020 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3021 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3022 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3023
3024 // Configure the diagnostics.
3025 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003026 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003027
3028 // Recover resources if we crash before exiting this function.
3029 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3030 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003031 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003032
Ahmed Charlesb8984322014-03-07 20:03:18 +00003033 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3034 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003035
3036 // Recover resources if we crash before exiting this function.
3037 llvm::CrashRecoveryContextCleanupRegistrar<
3038 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3039
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003040 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003041 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003042 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003043 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 }
3045
Ahmed Charlesb8984322014-03-07 20:03:18 +00003046 std::unique_ptr<std::vector<const char *>> Args(
3047 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
3049 // Recover resources if we crash before exiting this method.
3050 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3051 ArgsCleanup(Args.get());
3052
3053 // Since the Clang C library is primarily used by batch tools dealing with
3054 // (often very broken) source code, where spell-checking can have a
3055 // significant negative impact on performance (particularly when
3056 // precompiled headers are involved), we disable it by default.
3057 // Only do this if we haven't found a spell-checking-related argument.
3058 bool FoundSpellCheckingArgument = false;
3059 for (int I = 0; I != num_command_line_args; ++I) {
3060 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3061 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3062 FoundSpellCheckingArgument = true;
3063 break;
3064 }
3065 }
3066 if (!FoundSpellCheckingArgument)
3067 Args->push_back("-fno-spell-checking");
3068
3069 Args->insert(Args->end(), command_line_args,
3070 command_line_args + num_command_line_args);
3071
3072 // The 'source_filename' argument is optional. If the caller does not
3073 // specify it then it is assumed that the source file is specified
3074 // in the actual argument list.
3075 // Put the source file after command_line_args otherwise if '-x' flag is
3076 // present it will be unused.
3077 if (source_filename)
3078 Args->push_back(source_filename);
3079
3080 // Do we need the detailed preprocessing record?
3081 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3082 Args->push_back("-Xclang");
3083 Args->push_back("-detailed-preprocessing-record");
3084 }
3085
3086 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003087 std::unique_ptr<ASTUnit> ErrUnit;
3088 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003089 Args->data(), Args->data() + Args->size(),
3090 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003091 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3092 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3093 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3094 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3095 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3096 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003098 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003099 if (!Unit && !ErrUnit)
3100 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003101
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 if (NumErrors != Diags->getClient()->getNumErrors()) {
3103 // Make sure to check that 'Unit' is non-NULL.
3104 if (CXXIdx->getDisplayDiagnostics())
3105 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3106 }
3107
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003108 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3109 return CXError_ASTReadError;
3110
3111 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3112 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003113}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003114
3115CXTranslationUnit
3116clang_parseTranslationUnit(CXIndex CIdx,
3117 const char *source_filename,
3118 const char *const *command_line_args,
3119 int num_command_line_args,
3120 struct CXUnsavedFile *unsaved_files,
3121 unsigned num_unsaved_files,
3122 unsigned options) {
3123 CXTranslationUnit TU;
3124 enum CXErrorCode Result = clang_parseTranslationUnit2(
3125 CIdx, source_filename, command_line_args, num_command_line_args,
3126 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003127 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003128 assert((TU && Result == CXError_Success) ||
3129 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003130 return TU;
3131}
3132
3133enum CXErrorCode clang_parseTranslationUnit2(
3134 CXIndex CIdx,
3135 const char *source_filename,
3136 const char *const *command_line_args,
3137 int num_command_line_args,
3138 struct CXUnsavedFile *unsaved_files,
3139 unsigned num_unsaved_files,
3140 unsigned options,
3141 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003142 LOG_FUNC_SECTION {
3143 *Log << source_filename << ": ";
3144 for (int i = 0; i != num_command_line_args; ++i)
3145 *Log << command_line_args[i] << " ";
3146 }
3147
Alp Toker9d85b182014-07-07 01:23:14 +00003148 if (num_unsaved_files && !unsaved_files)
3149 return CXError_InvalidArguments;
3150
Alp Toker5c532982014-07-07 22:42:03 +00003151 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003152 auto ParseTranslationUnitImpl = [=, &result] {
3153 result = clang_parseTranslationUnit_Impl(
3154 CIdx, source_filename, command_line_args, num_command_line_args,
3155 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3156 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 llvm::CrashRecoveryContext CRC;
3158
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003159 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3161 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3162 fprintf(stderr, " 'command_line_args' : [");
3163 for (int i = 0; i != num_command_line_args; ++i) {
3164 if (i)
3165 fprintf(stderr, ", ");
3166 fprintf(stderr, "'%s'", command_line_args[i]);
3167 }
3168 fprintf(stderr, "],\n");
3169 fprintf(stderr, " 'unsaved_files' : [");
3170 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3171 if (i)
3172 fprintf(stderr, ", ");
3173 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3174 unsaved_files[i].Length);
3175 }
3176 fprintf(stderr, "],\n");
3177 fprintf(stderr, " 'options' : %d,\n", options);
3178 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003179
3180 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003182 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003183 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 }
Alp Toker5c532982014-07-07 22:42:03 +00003185
3186 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003187}
3188
3189unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3190 return CXSaveTranslationUnit_None;
3191}
3192
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003193static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3194 const char *FileName,
3195 unsigned options) {
3196 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3198 setThreadBackgroundPriority();
3199
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003200 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3201 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003202}
3203
3204int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3205 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003206 LOG_FUNC_SECTION {
3207 *Log << TU << ' ' << FileName;
3208 }
3209
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003210 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003211 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003213 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3217 if (!CXXUnit->hasSema())
3218 return CXSaveError_InvalidTU;
3219
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003220 CXSaveError result;
3221 auto SaveTranslationUnitImpl = [=, &result]() {
3222 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3223 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003224
3225 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3226 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003227 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003228
3229 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3230 PrintLibclangResourceUsage(TU);
3231
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003232 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 }
3234
3235 // We have an AST that has invalid nodes due to compiler errors.
3236 // Use a crash recovery thread for protection.
3237
3238 llvm::CrashRecoveryContext CRC;
3239
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003240 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3242 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3243 fprintf(stderr, " 'options' : %d,\n", options);
3244 fprintf(stderr, "}\n");
3245
3246 return CXSaveError_Unknown;
3247
3248 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3249 PrintLibclangResourceUsage(TU);
3250 }
3251
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003252 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003253}
3254
3255void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3256 if (CTUnit) {
3257 // If the translation unit has been marked as unsafe to free, just discard
3258 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003259 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3260 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 return;
3262
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003263 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003264 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3266 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003267 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 delete CTUnit;
3269 }
3270}
3271
3272unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3273 return CXReparse_None;
3274}
3275
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003276static CXErrorCode
3277clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3278 ArrayRef<CXUnsavedFile> unsaved_files,
3279 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003280 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003281 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003282 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003283 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003284 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
3286 // Reset the associated diagnostics.
3287 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003288 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003290 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3292 setThreadBackgroundPriority();
3293
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003294 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003296
3297 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3298 new std::vector<ASTUnit::RemappedFile>());
3299
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 // Recover resources if we crash before exiting this function.
3301 llvm::CrashRecoveryContextCleanupRegistrar<
3302 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003303
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003304 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003305 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003306 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003307 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003309
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003310 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3311 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003312 return CXError_Success;
3313 if (isASTReadError(CXXUnit))
3314 return CXError_ASTReadError;
3315 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316}
3317
3318int clang_reparseTranslationUnit(CXTranslationUnit TU,
3319 unsigned num_unsaved_files,
3320 struct CXUnsavedFile *unsaved_files,
3321 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003322 LOG_FUNC_SECTION {
3323 *Log << TU;
3324 }
3325
Alp Toker9d85b182014-07-07 01:23:14 +00003326 if (num_unsaved_files && !unsaved_files)
3327 return CXError_InvalidArguments;
3328
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003329 CXErrorCode result;
3330 auto ReparseTranslationUnitImpl = [=, &result]() {
3331 result = clang_reparseTranslationUnit_Impl(
3332 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3333 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
3335 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003336 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003337 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339
3340 llvm::CrashRecoveryContext CRC;
3341
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003342 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003344 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003345 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3347 PrintLibclangResourceUsage(TU);
3348
Alp Toker5c532982014-07-07 22:42:03 +00003349 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003350}
3351
3352
3353CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003354 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003355 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003356 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003357 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003358
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003359 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003360 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003361}
3362
3363CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003364 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003365 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003366 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003367 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003368
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003369 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3371}
3372
3373} // end: extern "C"
3374
3375//===----------------------------------------------------------------------===//
3376// CXFile Operations.
3377//===----------------------------------------------------------------------===//
3378
3379extern "C" {
3380CXString clang_getFileName(CXFile SFile) {
3381 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003382 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003383
3384 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003385 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386}
3387
3388time_t clang_getFileTime(CXFile SFile) {
3389 if (!SFile)
3390 return 0;
3391
3392 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3393 return FEnt->getModificationTime();
3394}
3395
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003396CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003397 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003398 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003399 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003400 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003401
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003402 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003403
3404 FileManager &FMgr = CXXUnit->getFileManager();
3405 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3406}
3407
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003408unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3409 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003410 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003411 LOG_BAD_TU(TU);
3412 return 0;
3413 }
3414
3415 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 return 0;
3417
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003418 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 FileEntry *FEnt = static_cast<FileEntry *>(file);
3420 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3421 .isFileMultipleIncludeGuarded(FEnt);
3422}
3423
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003424int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3425 if (!file || !outID)
3426 return 1;
3427
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003428 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003429 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3430 outID->data[0] = ID.getDevice();
3431 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003432 outID->data[2] = FEnt->getModificationTime();
3433 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003434}
3435
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003436int clang_File_isEqual(CXFile file1, CXFile file2) {
3437 if (file1 == file2)
3438 return true;
3439
3440 if (!file1 || !file2)
3441 return false;
3442
3443 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3444 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3445 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3446}
3447
Guy Benyei11169dd2012-12-18 14:30:41 +00003448} // end: extern "C"
3449
3450//===----------------------------------------------------------------------===//
3451// CXCursor Operations.
3452//===----------------------------------------------------------------------===//
3453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003454static const Decl *getDeclFromExpr(const Stmt *E) {
3455 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 return getDeclFromExpr(CE->getSubExpr());
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003460 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 if (PRE->isExplicitProperty())
3466 return PRE->getExplicitProperty();
3467 // It could be messaging both getter and setter as in:
3468 // ++myobj.myprop;
3469 // in which case prefer to associate the setter since it is less obvious
3470 // from inspecting the source that the setter is going to get called.
3471 if (PRE->isMessagingSetter())
3472 return PRE->getImplicitPropertySetter();
3473 return PRE->getImplicitPropertyGetter();
3474 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 if (Expr *Src = OVE->getSourceExpr())
3479 return getDeclFromExpr(Src);
3480
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003481 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 if (!CE->isElidable())
3485 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 return OME->getMethodDecl();
3488
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3493 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3496 isa<ParmVarDecl>(SizeOfPack->getPack()))
3497 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003498
3499 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003500}
3501
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003502static SourceLocation getLocationFromExpr(const Expr *E) {
3503 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 return getLocationFromExpr(CE->getSubExpr());
3505
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003506 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003508 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003510 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003512 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003514 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003516 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 return PropRef->getLocation();
3518
3519 return E->getLocStart();
3520}
3521
3522extern "C" {
3523
3524unsigned clang_visitChildren(CXCursor parent,
3525 CXCursorVisitor visitor,
3526 CXClientData client_data) {
3527 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3528 /*VisitPreprocessorLast=*/false);
3529 return CursorVis.VisitChildren(parent);
3530}
3531
3532#ifndef __has_feature
3533#define __has_feature(x) 0
3534#endif
3535#if __has_feature(blocks)
3536typedef enum CXChildVisitResult
3537 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3538
3539static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3540 CXClientData client_data) {
3541 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3542 return block(cursor, parent);
3543}
3544#else
3545// If we are compiled with a compiler that doesn't have native blocks support,
3546// define and call the block manually, so the
3547typedef struct _CXChildVisitResult
3548{
3549 void *isa;
3550 int flags;
3551 int reserved;
3552 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3553 CXCursor);
3554} *CXCursorVisitorBlock;
3555
3556static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3557 CXClientData client_data) {
3558 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3559 return block->invoke(block, cursor, parent);
3560}
3561#endif
3562
3563
3564unsigned clang_visitChildrenWithBlock(CXCursor parent,
3565 CXCursorVisitorBlock block) {
3566 return clang_visitChildren(parent, visitWithBlock, block);
3567}
3568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003569static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003571 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003572
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003573 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003575 if (const ObjCPropertyImplDecl *PropImpl =
3576 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003578 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003582 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003584 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 }
3586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003588 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003589
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003590 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3592 // and returns different names. NamedDecl returns the class name and
3593 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595
3596 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003597 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003598
3599 SmallString<1024> S;
3600 llvm::raw_svector_ostream os(S);
3601 ND->printName(os);
3602
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003603 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003604}
3605
3606CXString clang_getCursorSpelling(CXCursor C) {
3607 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003608 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003609
3610 if (clang_isReference(C.kind)) {
3611 switch (C.kind) {
3612 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003613 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003617 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 }
3620 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003621 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003626 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003627 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 }
3629 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003630 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 assert(Type && "Missing type decl");
3632
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 getAsString());
3635 }
3636 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003637 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 assert(Template && "Missing template decl");
3639
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003640 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642
3643 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003644 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 assert(NS && "Missing namespace decl");
3646
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003647 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 }
3649
3650 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003651 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 assert(Field && "Missing member decl");
3653
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003654 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 }
3656
3657 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003658 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 assert(Label && "Missing label");
3660
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 }
3663
3664 case CXCursor_OverloadedDeclRef: {
3665 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003666 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3667 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003668 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003669 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003671 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003672 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 OverloadedTemplateStorage *Ovl
3674 = Storage.get<OverloadedTemplateStorage*>();
3675 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003676 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003677 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 }
3679
3680 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003681 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 assert(Var && "Missing variable decl");
3683
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003684 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686
3687 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 }
3690 }
3691
3692 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003693 const Expr *E = getCursorExpr(C);
3694
3695 if (C.kind == CXCursor_ObjCStringLiteral ||
3696 C.kind == CXCursor_StringLiteral) {
3697 const StringLiteral *SLit;
3698 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3699 SLit = OSL->getString();
3700 } else {
3701 SLit = cast<StringLiteral>(E);
3702 }
3703 SmallString<256> Buf;
3704 llvm::raw_svector_ostream OS(Buf);
3705 SLit->outputString(OS);
3706 return cxstring::createDup(OS.str());
3707 }
3708
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003709 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 if (D)
3711 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003712 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 }
3714
3715 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003716 const Stmt *S = getCursorStmt(C);
3717 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003719
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003720 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722
3723 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 ->getNameStart());
3726
3727 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 ->getNameStart());
3730
3731 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003732 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003733
3734 if (clang_isDeclaration(C.kind))
3735 return getDeclSpelling(getCursorDecl(C));
3736
3737 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003738 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003739 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 }
3741
3742 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003743 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003744 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 }
3746
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003747 if (C.kind == CXCursor_PackedAttr) {
3748 return cxstring::createRef("packed");
3749 }
3750
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003751 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003752}
3753
3754CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3755 unsigned pieceIndex,
3756 unsigned options) {
3757 if (clang_Cursor_isNull(C))
3758 return clang_getNullRange();
3759
3760 ASTContext &Ctx = getCursorContext(C);
3761
3762 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003763 const Stmt *S = getCursorStmt(C);
3764 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 if (pieceIndex > 0)
3766 return clang_getNullRange();
3767 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3768 }
3769
3770 return clang_getNullRange();
3771 }
3772
3773 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003774 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3776 if (pieceIndex >= ME->getNumSelectorLocs())
3777 return clang_getNullRange();
3778 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3779 }
3780 }
3781
3782 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3783 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003784 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3786 if (pieceIndex >= MD->getNumSelectorLocs())
3787 return clang_getNullRange();
3788 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3789 }
3790 }
3791
3792 if (C.kind == CXCursor_ObjCCategoryDecl ||
3793 C.kind == CXCursor_ObjCCategoryImplDecl) {
3794 if (pieceIndex > 0)
3795 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003796 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3798 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003799 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3801 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3802 }
3803
3804 if (C.kind == CXCursor_ModuleImportDecl) {
3805 if (pieceIndex > 0)
3806 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003807 if (const ImportDecl *ImportD =
3808 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3810 if (!Locs.empty())
3811 return cxloc::translateSourceRange(Ctx,
3812 SourceRange(Locs.front(), Locs.back()));
3813 }
3814 return clang_getNullRange();
3815 }
3816
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003817 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3818 C.kind == CXCursor_ConversionFunction) {
3819 if (pieceIndex > 0)
3820 return clang_getNullRange();
3821 if (const FunctionDecl *FD =
3822 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3823 DeclarationNameInfo FunctionName = FD->getNameInfo();
3824 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3825 }
3826 return clang_getNullRange();
3827 }
3828
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 // FIXME: A CXCursor_InclusionDirective should give the location of the
3830 // filename, but we don't keep track of this.
3831
3832 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3833 // but we don't keep track of this.
3834
3835 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3836 // but we don't keep track of this.
3837
3838 // Default handling, give the location of the cursor.
3839
3840 if (pieceIndex > 0)
3841 return clang_getNullRange();
3842
3843 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3844 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3845 return cxloc::translateSourceRange(Ctx, Loc);
3846}
3847
Eli Bendersky44a206f2014-07-31 18:04:56 +00003848CXString clang_Cursor_getMangling(CXCursor C) {
3849 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3850 return cxstring::createEmpty();
3851
Eli Bendersky44a206f2014-07-31 18:04:56 +00003852 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003853 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003854 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3855 return cxstring::createEmpty();
3856
Eli Bendersky79759592014-08-01 15:01:10 +00003857 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003858 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003859 ASTContext &Ctx = ND->getASTContext();
3860 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003861
Eli Bendersky79759592014-08-01 15:01:10 +00003862 std::string FrontendBuf;
3863 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3864 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003865
Eli Bendersky79759592014-08-01 15:01:10 +00003866 // Now apply backend mangling.
3867 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003868 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003869
3870 std::string FinalBuf;
3871 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003872 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3873 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003874
3875 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003876}
3877
Guy Benyei11169dd2012-12-18 14:30:41 +00003878CXString clang_getCursorDisplayName(CXCursor C) {
3879 if (!clang_isDeclaration(C.kind))
3880 return clang_getCursorSpelling(C);
3881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003882 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003884 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003885
3886 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003887 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 D = FunTmpl->getTemplatedDecl();
3889
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 SmallString<64> Str;
3892 llvm::raw_svector_ostream OS(Str);
3893 OS << *Function;
3894 if (Function->getPrimaryTemplate())
3895 OS << "<>";
3896 OS << "(";
3897 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3898 if (I)
3899 OS << ", ";
3900 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3901 }
3902
3903 if (Function->isVariadic()) {
3904 if (Function->getNumParams())
3905 OS << ", ";
3906 OS << "...";
3907 }
3908 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003909 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 }
3911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 SmallString<64> Str;
3914 llvm::raw_svector_ostream OS(Str);
3915 OS << *ClassTemplate;
3916 OS << "<";
3917 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3918 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3919 if (I)
3920 OS << ", ";
3921
3922 NamedDecl *Param = Params->getParam(I);
3923 if (Param->getIdentifier()) {
3924 OS << Param->getIdentifier()->getName();
3925 continue;
3926 }
3927
3928 // There is no parameter name, which makes this tricky. Try to come up
3929 // with something useful that isn't too long.
3930 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3931 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3932 else if (NonTypeTemplateParmDecl *NTTP
3933 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3934 OS << NTTP->getType().getAsString(Policy);
3935 else
3936 OS << "template<...> class";
3937 }
3938
3939 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003940 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 }
3942
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003943 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3945 // If the type was explicitly written, use that.
3946 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003947 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003948
Benjamin Kramer9170e912013-02-22 15:46:01 +00003949 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 llvm::raw_svector_ostream OS(Str);
3951 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003952 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 ClassSpec->getTemplateArgs().data(),
3954 ClassSpec->getTemplateArgs().size(),
3955 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003956 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 }
3958
3959 return clang_getCursorSpelling(C);
3960}
3961
3962CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3963 switch (Kind) {
3964 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004092 case CXCursor_ObjCSelfExpr:
4093 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004182 case CXCursor_SEHLeaveStmt:
4183 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004212 case CXCursor_PackedAttr:
4213 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004214 case CXCursor_PureAttr:
4215 return cxstring::createRef("attribute(pure)");
4216 case CXCursor_ConstAttr:
4217 return cxstring::createRef("attribute(const)");
4218 case CXCursor_NoDuplicateAttr:
4219 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004220 case CXCursor_CUDAConstantAttr:
4221 return cxstring::createRef("attribute(constant)");
4222 case CXCursor_CUDADeviceAttr:
4223 return cxstring::createRef("attribute(device)");
4224 case CXCursor_CUDAGlobalAttr:
4225 return cxstring::createRef("attribute(global)");
4226 case CXCursor_CUDAHostAttr:
4227 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004228 case CXCursor_CUDASharedAttr:
4229 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004278 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004279 return cxstring::createRef("OMPParallelDirective");
4280 case CXCursor_OMPSimdDirective:
4281 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004282 case CXCursor_OMPForDirective:
4283 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004284 case CXCursor_OMPForSimdDirective:
4285 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004286 case CXCursor_OMPSectionsDirective:
4287 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004288 case CXCursor_OMPSectionDirective:
4289 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004290 case CXCursor_OMPSingleDirective:
4291 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004292 case CXCursor_OMPMasterDirective:
4293 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004294 case CXCursor_OMPCriticalDirective:
4295 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004296 case CXCursor_OMPParallelForDirective:
4297 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004298 case CXCursor_OMPParallelForSimdDirective:
4299 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004300 case CXCursor_OMPParallelSectionsDirective:
4301 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004302 case CXCursor_OMPTaskDirective:
4303 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004304 case CXCursor_OMPTaskyieldDirective:
4305 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004306 case CXCursor_OMPBarrierDirective:
4307 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004308 case CXCursor_OMPTaskwaitDirective:
4309 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004310 case CXCursor_OMPTaskgroupDirective:
4311 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004312 case CXCursor_OMPFlushDirective:
4313 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004314 case CXCursor_OMPOrderedDirective:
4315 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004316 case CXCursor_OMPAtomicDirective:
4317 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004318 case CXCursor_OMPTargetDirective:
4319 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004320 case CXCursor_OMPTargetDataDirective:
4321 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004322 case CXCursor_OMPTeamsDirective:
4323 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004324 case CXCursor_OMPCancellationPointDirective:
4325 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004326 case CXCursor_OMPCancelDirective:
4327 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004328 case CXCursor_OverloadCandidate:
4329 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 }
4331
4332 llvm_unreachable("Unhandled CXCursorKind");
4333}
4334
4335struct GetCursorData {
4336 SourceLocation TokenBeginLoc;
4337 bool PointsAtMacroArgExpansion;
4338 bool VisitedObjCPropertyImplDecl;
4339 SourceLocation VisitedDeclaratorDeclStartLoc;
4340 CXCursor &BestCursor;
4341
4342 GetCursorData(SourceManager &SM,
4343 SourceLocation tokenBegin, CXCursor &outputCursor)
4344 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4345 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4346 VisitedObjCPropertyImplDecl = false;
4347 }
4348};
4349
4350static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4351 CXCursor parent,
4352 CXClientData client_data) {
4353 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4354 CXCursor *BestCursor = &Data->BestCursor;
4355
4356 // If we point inside a macro argument we should provide info of what the
4357 // token is so use the actual cursor, don't replace it with a macro expansion
4358 // cursor.
4359 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4360 return CXChildVisit_Recurse;
4361
4362 if (clang_isDeclaration(cursor.kind)) {
4363 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004364 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4366 if (MD->isImplicit())
4367 return CXChildVisit_Break;
4368
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004369 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4371 // Check that when we have multiple @class references in the same line,
4372 // that later ones do not override the previous ones.
4373 // If we have:
4374 // @class Foo, Bar;
4375 // source ranges for both start at '@', so 'Bar' will end up overriding
4376 // 'Foo' even though the cursor location was at 'Foo'.
4377 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4378 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004379 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4381 if (PrevID != ID &&
4382 !PrevID->isThisDeclarationADefinition() &&
4383 !ID->isThisDeclarationADefinition())
4384 return CXChildVisit_Break;
4385 }
4386
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004387 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4389 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4390 // Check that when we have multiple declarators in the same line,
4391 // that later ones do not override the previous ones.
4392 // If we have:
4393 // int Foo, Bar;
4394 // source ranges for both start at 'int', so 'Bar' will end up overriding
4395 // 'Foo' even though the cursor location was at 'Foo'.
4396 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4397 return CXChildVisit_Break;
4398 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4402 (void)PropImp;
4403 // Check that when we have multiple @synthesize in the same line,
4404 // that later ones do not override the previous ones.
4405 // If we have:
4406 // @synthesize Foo, Bar;
4407 // source ranges for both start at '@', so 'Bar' will end up overriding
4408 // 'Foo' even though the cursor location was at 'Foo'.
4409 if (Data->VisitedObjCPropertyImplDecl)
4410 return CXChildVisit_Break;
4411 Data->VisitedObjCPropertyImplDecl = true;
4412 }
4413 }
4414
4415 if (clang_isExpression(cursor.kind) &&
4416 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 // Avoid having the cursor of an expression replace the declaration cursor
4419 // when the expression source range overlaps the declaration range.
4420 // This can happen for C++ constructor expressions whose range generally
4421 // include the variable declaration, e.g.:
4422 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4423 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4424 D->getLocation() == Data->TokenBeginLoc)
4425 return CXChildVisit_Break;
4426 }
4427 }
4428
4429 // If our current best cursor is the construction of a temporary object,
4430 // don't replace that cursor with a type reference, because we want
4431 // clang_getCursor() to point at the constructor.
4432 if (clang_isExpression(BestCursor->kind) &&
4433 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4434 cursor.kind == CXCursor_TypeRef) {
4435 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4436 // as having the actual point on the type reference.
4437 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4438 return CXChildVisit_Recurse;
4439 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004440
4441 // If we already have an Objective-C superclass reference, don't
4442 // update it further.
4443 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4444 return CXChildVisit_Break;
4445
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 *BestCursor = cursor;
4447 return CXChildVisit_Recurse;
4448}
4449
4450CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004451 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004452 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004454 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004455
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004456 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4458
4459 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4460 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4461
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004462 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 CXFile SearchFile;
4464 unsigned SearchLine, SearchColumn;
4465 CXFile ResultFile;
4466 unsigned ResultLine, ResultColumn;
4467 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4468 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4469 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004470
4471 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4472 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004473 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004474 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 SearchFileName = clang_getFileName(SearchFile);
4476 ResultFileName = clang_getFileName(ResultFile);
4477 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4478 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004479 *Log << llvm::format("(%s:%d:%d) = %s",
4480 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4481 clang_getCString(KindSpelling))
4482 << llvm::format("(%s:%d:%d):%s%s",
4483 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4484 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 clang_disposeString(SearchFileName);
4486 clang_disposeString(ResultFileName);
4487 clang_disposeString(KindSpelling);
4488 clang_disposeString(USR);
4489
4490 CXCursor Definition = clang_getCursorDefinition(Result);
4491 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4492 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4493 CXString DefinitionKindSpelling
4494 = clang_getCursorKindSpelling(Definition.kind);
4495 CXFile DefinitionFile;
4496 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004497 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004498 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004500 *Log << llvm::format(" -> %s(%s:%d:%d)",
4501 clang_getCString(DefinitionKindSpelling),
4502 clang_getCString(DefinitionFileName),
4503 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 clang_disposeString(DefinitionFileName);
4505 clang_disposeString(DefinitionKindSpelling);
4506 }
4507 }
4508
4509 return Result;
4510}
4511
4512CXCursor clang_getNullCursor(void) {
4513 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4514}
4515
4516unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004517 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4518 // can't set consistently. For example, when visiting a DeclStmt we will set
4519 // it but we don't set it on the result of clang_getCursorDefinition for
4520 // a reference of the same declaration.
4521 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4522 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4523 // to provide that kind of info.
4524 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004525 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004526 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004527 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004528
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return X == Y;
4530}
4531
4532unsigned clang_hashCursor(CXCursor C) {
4533 unsigned Index = 0;
4534 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4535 Index = 1;
4536
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004537 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 std::make_pair(C.kind, C.data[Index]));
4539}
4540
4541unsigned clang_isInvalid(enum CXCursorKind K) {
4542 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4543}
4544
4545unsigned clang_isDeclaration(enum CXCursorKind K) {
4546 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4547 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4548}
4549
4550unsigned clang_isReference(enum CXCursorKind K) {
4551 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4552}
4553
4554unsigned clang_isExpression(enum CXCursorKind K) {
4555 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4556}
4557
4558unsigned clang_isStatement(enum CXCursorKind K) {
4559 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4560}
4561
4562unsigned clang_isAttribute(enum CXCursorKind K) {
4563 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4564}
4565
4566unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4567 return K == CXCursor_TranslationUnit;
4568}
4569
4570unsigned clang_isPreprocessing(enum CXCursorKind K) {
4571 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4572}
4573
4574unsigned clang_isUnexposed(enum CXCursorKind K) {
4575 switch (K) {
4576 case CXCursor_UnexposedDecl:
4577 case CXCursor_UnexposedExpr:
4578 case CXCursor_UnexposedStmt:
4579 case CXCursor_UnexposedAttr:
4580 return true;
4581 default:
4582 return false;
4583 }
4584}
4585
4586CXCursorKind clang_getCursorKind(CXCursor C) {
4587 return C.kind;
4588}
4589
4590CXSourceLocation clang_getCursorLocation(CXCursor C) {
4591 if (clang_isReference(C.kind)) {
4592 switch (C.kind) {
4593 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004594 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 = getCursorObjCSuperClassRef(C);
4596 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4597 }
4598
4599 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004600 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 = getCursorObjCProtocolRef(C);
4602 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4603 }
4604
4605 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004606 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 = getCursorObjCClassRef(C);
4608 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4609 }
4610
4611 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004612 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4614 }
4615
4616 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004617 std::pair<const TemplateDecl *, SourceLocation> P =
4618 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4620 }
4621
4622 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004623 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4625 }
4626
4627 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004628 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4630 }
4631
4632 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4635 }
4636
4637 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004638 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 if (!BaseSpec)
4640 return clang_getNullLocation();
4641
4642 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4643 return cxloc::translateSourceLocation(getCursorContext(C),
4644 TSInfo->getTypeLoc().getBeginLoc());
4645
4646 return cxloc::translateSourceLocation(getCursorContext(C),
4647 BaseSpec->getLocStart());
4648 }
4649
4650 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004651 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4653 }
4654
4655 case CXCursor_OverloadedDeclRef:
4656 return cxloc::translateSourceLocation(getCursorContext(C),
4657 getCursorOverloadedDeclRef(C).second);
4658
4659 default:
4660 // FIXME: Need a way to enumerate all non-reference cases.
4661 llvm_unreachable("Missed a reference kind");
4662 }
4663 }
4664
4665 if (clang_isExpression(C.kind))
4666 return cxloc::translateSourceLocation(getCursorContext(C),
4667 getLocationFromExpr(getCursorExpr(C)));
4668
4669 if (clang_isStatement(C.kind))
4670 return cxloc::translateSourceLocation(getCursorContext(C),
4671 getCursorStmt(C)->getLocStart());
4672
4673 if (C.kind == CXCursor_PreprocessingDirective) {
4674 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4675 return cxloc::translateSourceLocation(getCursorContext(C), L);
4676 }
4677
4678 if (C.kind == CXCursor_MacroExpansion) {
4679 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004680 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 return cxloc::translateSourceLocation(getCursorContext(C), L);
4682 }
4683
4684 if (C.kind == CXCursor_MacroDefinition) {
4685 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4686 return cxloc::translateSourceLocation(getCursorContext(C), L);
4687 }
4688
4689 if (C.kind == CXCursor_InclusionDirective) {
4690 SourceLocation L
4691 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4692 return cxloc::translateSourceLocation(getCursorContext(C), L);
4693 }
4694
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004695 if (clang_isAttribute(C.kind)) {
4696 SourceLocation L
4697 = cxcursor::getCursorAttr(C)->getLocation();
4698 return cxloc::translateSourceLocation(getCursorContext(C), L);
4699 }
4700
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 if (!clang_isDeclaration(C.kind))
4702 return clang_getNullLocation();
4703
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004704 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 if (!D)
4706 return clang_getNullLocation();
4707
4708 SourceLocation Loc = D->getLocation();
4709 // FIXME: Multiple variables declared in a single declaration
4710 // currently lack the information needed to correctly determine their
4711 // ranges when accounting for the type-specifier. We use context
4712 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4713 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004714 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 if (!cxcursor::isFirstInDeclGroup(C))
4716 Loc = VD->getLocation();
4717 }
4718
4719 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004720 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 Loc = MD->getSelectorStartLoc();
4722
4723 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4724}
4725
4726} // end extern "C"
4727
4728CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4729 assert(TU);
4730
4731 // Guard against an invalid SourceLocation, or we may assert in one
4732 // of the following calls.
4733 if (SLoc.isInvalid())
4734 return clang_getNullCursor();
4735
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004736 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004737
4738 // Translate the given source location to make it point at the beginning of
4739 // the token under the cursor.
4740 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4741 CXXUnit->getASTContext().getLangOpts());
4742
4743 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4744 if (SLoc.isValid()) {
4745 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4746 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4747 /*VisitPreprocessorLast=*/true,
4748 /*VisitIncludedEntities=*/false,
4749 SourceLocation(SLoc));
4750 CursorVis.visitFileRegion();
4751 }
4752
4753 return Result;
4754}
4755
4756static SourceRange getRawCursorExtent(CXCursor C) {
4757 if (clang_isReference(C.kind)) {
4758 switch (C.kind) {
4759 case CXCursor_ObjCSuperClassRef:
4760 return getCursorObjCSuperClassRef(C).second;
4761
4762 case CXCursor_ObjCProtocolRef:
4763 return getCursorObjCProtocolRef(C).second;
4764
4765 case CXCursor_ObjCClassRef:
4766 return getCursorObjCClassRef(C).second;
4767
4768 case CXCursor_TypeRef:
4769 return getCursorTypeRef(C).second;
4770
4771 case CXCursor_TemplateRef:
4772 return getCursorTemplateRef(C).second;
4773
4774 case CXCursor_NamespaceRef:
4775 return getCursorNamespaceRef(C).second;
4776
4777 case CXCursor_MemberRef:
4778 return getCursorMemberRef(C).second;
4779
4780 case CXCursor_CXXBaseSpecifier:
4781 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4782
4783 case CXCursor_LabelRef:
4784 return getCursorLabelRef(C).second;
4785
4786 case CXCursor_OverloadedDeclRef:
4787 return getCursorOverloadedDeclRef(C).second;
4788
4789 case CXCursor_VariableRef:
4790 return getCursorVariableRef(C).second;
4791
4792 default:
4793 // FIXME: Need a way to enumerate all non-reference cases.
4794 llvm_unreachable("Missed a reference kind");
4795 }
4796 }
4797
4798 if (clang_isExpression(C.kind))
4799 return getCursorExpr(C)->getSourceRange();
4800
4801 if (clang_isStatement(C.kind))
4802 return getCursorStmt(C)->getSourceRange();
4803
4804 if (clang_isAttribute(C.kind))
4805 return getCursorAttr(C)->getRange();
4806
4807 if (C.kind == CXCursor_PreprocessingDirective)
4808 return cxcursor::getCursorPreprocessingDirective(C);
4809
4810 if (C.kind == CXCursor_MacroExpansion) {
4811 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004812 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 return TU->mapRangeFromPreamble(Range);
4814 }
4815
4816 if (C.kind == CXCursor_MacroDefinition) {
4817 ASTUnit *TU = getCursorASTUnit(C);
4818 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4819 return TU->mapRangeFromPreamble(Range);
4820 }
4821
4822 if (C.kind == CXCursor_InclusionDirective) {
4823 ASTUnit *TU = getCursorASTUnit(C);
4824 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4825 return TU->mapRangeFromPreamble(Range);
4826 }
4827
4828 if (C.kind == CXCursor_TranslationUnit) {
4829 ASTUnit *TU = getCursorASTUnit(C);
4830 FileID MainID = TU->getSourceManager().getMainFileID();
4831 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4832 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4833 return SourceRange(Start, End);
4834 }
4835
4836 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 if (!D)
4839 return SourceRange();
4840
4841 SourceRange R = D->getSourceRange();
4842 // FIXME: Multiple variables declared in a single declaration
4843 // currently lack the information needed to correctly determine their
4844 // ranges when accounting for the type-specifier. We use context
4845 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4846 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004847 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 if (!cxcursor::isFirstInDeclGroup(C))
4849 R.setBegin(VD->getLocation());
4850 }
4851 return R;
4852 }
4853 return SourceRange();
4854}
4855
4856/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4857/// the decl-specifier-seq for declarations.
4858static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4859 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 if (!D)
4862 return SourceRange();
4863
4864 SourceRange R = D->getSourceRange();
4865
4866 // Adjust the start of the location for declarations preceded by
4867 // declaration specifiers.
4868 SourceLocation StartLoc;
4869 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4870 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4871 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004872 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4874 StartLoc = TI->getTypeLoc().getLocStart();
4875 }
4876
4877 if (StartLoc.isValid() && R.getBegin().isValid() &&
4878 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4879 R.setBegin(StartLoc);
4880
4881 // FIXME: Multiple variables declared in a single declaration
4882 // currently lack the information needed to correctly determine their
4883 // ranges when accounting for the type-specifier. We use context
4884 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4885 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 if (!cxcursor::isFirstInDeclGroup(C))
4888 R.setBegin(VD->getLocation());
4889 }
4890
4891 return R;
4892 }
4893
4894 return getRawCursorExtent(C);
4895}
4896
4897extern "C" {
4898
4899CXSourceRange clang_getCursorExtent(CXCursor C) {
4900 SourceRange R = getRawCursorExtent(C);
4901 if (R.isInvalid())
4902 return clang_getNullRange();
4903
4904 return cxloc::translateSourceRange(getCursorContext(C), R);
4905}
4906
4907CXCursor clang_getCursorReferenced(CXCursor C) {
4908 if (clang_isInvalid(C.kind))
4909 return clang_getNullCursor();
4910
4911 CXTranslationUnit tu = getCursorTU(C);
4912 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 if (!D)
4915 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004918 if (const ObjCPropertyImplDecl *PropImpl =
4919 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4921 return MakeCXCursor(Property, tu);
4922
4923 return C;
4924 }
4925
4926 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004927 const Expr *E = getCursorExpr(C);
4928 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 if (D) {
4930 CXCursor declCursor = MakeCXCursor(D, tu);
4931 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4932 declCursor);
4933 return declCursor;
4934 }
4935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004936 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 return MakeCursorOverloadedDeclRef(Ovl, tu);
4938
4939 return clang_getNullCursor();
4940 }
4941
4942 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004943 const Stmt *S = getCursorStmt(C);
4944 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 if (LabelDecl *label = Goto->getLabel())
4946 if (LabelStmt *labelS = label->getStmt())
4947 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4948
4949 return clang_getNullCursor();
4950 }
Richard Smith66a81862015-05-04 02:25:31 +00004951
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004953 if (const MacroDefinitionRecord *Def =
4954 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 return MakeMacroDefinitionCursor(Def, tu);
4956 }
4957
4958 if (!clang_isReference(C.kind))
4959 return clang_getNullCursor();
4960
4961 switch (C.kind) {
4962 case CXCursor_ObjCSuperClassRef:
4963 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4964
4965 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004966 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4967 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 return MakeCXCursor(Def, tu);
4969
4970 return MakeCXCursor(Prot, tu);
4971 }
4972
4973 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004974 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4975 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 return MakeCXCursor(Def, tu);
4977
4978 return MakeCXCursor(Class, tu);
4979 }
4980
4981 case CXCursor_TypeRef:
4982 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4983
4984 case CXCursor_TemplateRef:
4985 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4986
4987 case CXCursor_NamespaceRef:
4988 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4989
4990 case CXCursor_MemberRef:
4991 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4992
4993 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004994 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004995 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4996 tu ));
4997 }
4998
4999 case CXCursor_LabelRef:
5000 // FIXME: We end up faking the "parent" declaration here because we
5001 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005002 return MakeCXCursor(getCursorLabelRef(C).first,
5003 cxtu::getASTUnit(tu)->getASTContext()
5004 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 tu);
5006
5007 case CXCursor_OverloadedDeclRef:
5008 return C;
5009
5010 case CXCursor_VariableRef:
5011 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5012
5013 default:
5014 // We would prefer to enumerate all non-reference cursor kinds here.
5015 llvm_unreachable("Unhandled reference cursor kind");
5016 }
5017}
5018
5019CXCursor clang_getCursorDefinition(CXCursor C) {
5020 if (clang_isInvalid(C.kind))
5021 return clang_getNullCursor();
5022
5023 CXTranslationUnit TU = getCursorTU(C);
5024
5025 bool WasReference = false;
5026 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5027 C = clang_getCursorReferenced(C);
5028 WasReference = true;
5029 }
5030
5031 if (C.kind == CXCursor_MacroExpansion)
5032 return clang_getCursorReferenced(C);
5033
5034 if (!clang_isDeclaration(C.kind))
5035 return clang_getNullCursor();
5036
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005037 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (!D)
5039 return clang_getNullCursor();
5040
5041 switch (D->getKind()) {
5042 // Declaration kinds that don't really separate the notions of
5043 // declaration and definition.
5044 case Decl::Namespace:
5045 case Decl::Typedef:
5046 case Decl::TypeAlias:
5047 case Decl::TypeAliasTemplate:
5048 case Decl::TemplateTypeParm:
5049 case Decl::EnumConstant:
5050 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005051 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 case Decl::IndirectField:
5053 case Decl::ObjCIvar:
5054 case Decl::ObjCAtDefsField:
5055 case Decl::ImplicitParam:
5056 case Decl::ParmVar:
5057 case Decl::NonTypeTemplateParm:
5058 case Decl::TemplateTemplateParm:
5059 case Decl::ObjCCategoryImpl:
5060 case Decl::ObjCImplementation:
5061 case Decl::AccessSpec:
5062 case Decl::LinkageSpec:
5063 case Decl::ObjCPropertyImpl:
5064 case Decl::FileScopeAsm:
5065 case Decl::StaticAssert:
5066 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005067 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 case Decl::Label: // FIXME: Is this right??
5069 case Decl::ClassScopeFunctionSpecialization:
5070 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005071 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005072 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 return C;
5074
5075 // Declaration kinds that don't make any sense here, but are
5076 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005077 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005079 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 break;
5081
5082 // Declaration kinds for which the definition is not resolvable.
5083 case Decl::UnresolvedUsingTypename:
5084 case Decl::UnresolvedUsingValue:
5085 break;
5086
5087 case Decl::UsingDirective:
5088 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5089 TU);
5090
5091 case Decl::NamespaceAlias:
5092 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5093
5094 case Decl::Enum:
5095 case Decl::Record:
5096 case Decl::CXXRecord:
5097 case Decl::ClassTemplateSpecialization:
5098 case Decl::ClassTemplatePartialSpecialization:
5099 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5100 return MakeCXCursor(Def, TU);
5101 return clang_getNullCursor();
5102
5103 case Decl::Function:
5104 case Decl::CXXMethod:
5105 case Decl::CXXConstructor:
5106 case Decl::CXXDestructor:
5107 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005108 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005110 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 return clang_getNullCursor();
5112 }
5113
Larisse Voufo39a1e502013-08-06 01:03:05 +00005114 case Decl::Var:
5115 case Decl::VarTemplateSpecialization:
5116 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005118 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 return MakeCXCursor(Def, TU);
5120 return clang_getNullCursor();
5121 }
5122
5123 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005124 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5126 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5127 return clang_getNullCursor();
5128 }
5129
5130 case Decl::ClassTemplate: {
5131 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5132 ->getDefinition())
5133 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5134 TU);
5135 return clang_getNullCursor();
5136 }
5137
Larisse Voufo39a1e502013-08-06 01:03:05 +00005138 case Decl::VarTemplate: {
5139 if (VarDecl *Def =
5140 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5141 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5142 return clang_getNullCursor();
5143 }
5144
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 case Decl::Using:
5146 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5147 D->getLocation(), TU);
5148
5149 case Decl::UsingShadow:
5150 return clang_getCursorDefinition(
5151 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5152 TU));
5153
5154 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005155 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 if (Method->isThisDeclarationADefinition())
5157 return C;
5158
5159 // Dig out the method definition in the associated
5160 // @implementation, if we have it.
5161 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005162 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5164 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5165 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5166 Method->isInstanceMethod()))
5167 if (Def->isThisDeclarationADefinition())
5168 return MakeCXCursor(Def, TU);
5169
5170 return clang_getNullCursor();
5171 }
5172
5173 case Decl::ObjCCategory:
5174 if (ObjCCategoryImplDecl *Impl
5175 = cast<ObjCCategoryDecl>(D)->getImplementation())
5176 return MakeCXCursor(Impl, TU);
5177 return clang_getNullCursor();
5178
5179 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005180 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 return MakeCXCursor(Def, TU);
5182 return clang_getNullCursor();
5183
5184 case Decl::ObjCInterface: {
5185 // There are two notions of a "definition" for an Objective-C
5186 // class: the interface and its implementation. When we resolved a
5187 // reference to an Objective-C class, produce the @interface as
5188 // the definition; when we were provided with the interface,
5189 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005190 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005192 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 return MakeCXCursor(Def, TU);
5194 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5195 return MakeCXCursor(Impl, TU);
5196 return clang_getNullCursor();
5197 }
5198
5199 case Decl::ObjCProperty:
5200 // FIXME: We don't really know where to find the
5201 // ObjCPropertyImplDecls that implement this property.
5202 return clang_getNullCursor();
5203
5204 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005205 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005207 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 return MakeCXCursor(Def, TU);
5209
5210 return clang_getNullCursor();
5211
5212 case Decl::Friend:
5213 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5214 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5215 return clang_getNullCursor();
5216
5217 case Decl::FriendTemplate:
5218 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5219 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5220 return clang_getNullCursor();
5221 }
5222
5223 return clang_getNullCursor();
5224}
5225
5226unsigned clang_isCursorDefinition(CXCursor C) {
5227 if (!clang_isDeclaration(C.kind))
5228 return 0;
5229
5230 return clang_getCursorDefinition(C) == C;
5231}
5232
5233CXCursor clang_getCanonicalCursor(CXCursor C) {
5234 if (!clang_isDeclaration(C.kind))
5235 return C;
5236
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005237 if (const Decl *D = getCursorDecl(C)) {
5238 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5240 return MakeCXCursor(CatD, getCursorTU(C));
5241
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005242 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5243 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 return MakeCXCursor(IFD, getCursorTU(C));
5245
5246 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5247 }
5248
5249 return C;
5250}
5251
5252int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5253 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5254}
5255
5256unsigned clang_getNumOverloadedDecls(CXCursor C) {
5257 if (C.kind != CXCursor_OverloadedDeclRef)
5258 return 0;
5259
5260 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005261 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 return E->getNumDecls();
5263
5264 if (OverloadedTemplateStorage *S
5265 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5266 return S->size();
5267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005268 const Decl *D = Storage.get<const Decl *>();
5269 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 return Using->shadow_size();
5271
5272 return 0;
5273}
5274
5275CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5276 if (cursor.kind != CXCursor_OverloadedDeclRef)
5277 return clang_getNullCursor();
5278
5279 if (index >= clang_getNumOverloadedDecls(cursor))
5280 return clang_getNullCursor();
5281
5282 CXTranslationUnit TU = getCursorTU(cursor);
5283 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005284 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 return MakeCXCursor(E->decls_begin()[index], TU);
5286
5287 if (OverloadedTemplateStorage *S
5288 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5289 return MakeCXCursor(S->begin()[index], TU);
5290
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005291 const Decl *D = Storage.get<const Decl *>();
5292 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 // FIXME: This is, unfortunately, linear time.
5294 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5295 std::advance(Pos, index);
5296 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5297 }
5298
5299 return clang_getNullCursor();
5300}
5301
5302void clang_getDefinitionSpellingAndExtent(CXCursor C,
5303 const char **startBuf,
5304 const char **endBuf,
5305 unsigned *startLine,
5306 unsigned *startColumn,
5307 unsigned *endLine,
5308 unsigned *endColumn) {
5309 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005310 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5312
5313 SourceManager &SM = FD->getASTContext().getSourceManager();
5314 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5315 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5316 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5317 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5318 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5319 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5320}
5321
5322
5323CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5324 unsigned PieceIndex) {
5325 RefNamePieces Pieces;
5326
5327 switch (C.kind) {
5328 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005329 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5331 E->getQualifierLoc().getSourceRange());
5332 break;
5333
5334 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005335 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5337 E->getQualifierLoc().getSourceRange(),
5338 E->getOptionalExplicitTemplateArgs());
5339 break;
5340
5341 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005342 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005344 const Expr *Callee = OCE->getCallee();
5345 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 Callee = ICE->getSubExpr();
5347
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005348 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5350 DRE->getQualifierLoc().getSourceRange());
5351 }
5352 break;
5353
5354 default:
5355 break;
5356 }
5357
5358 if (Pieces.empty()) {
5359 if (PieceIndex == 0)
5360 return clang_getCursorExtent(C);
5361 } else if (PieceIndex < Pieces.size()) {
5362 SourceRange R = Pieces[PieceIndex];
5363 if (R.isValid())
5364 return cxloc::translateSourceRange(getCursorContext(C), R);
5365 }
5366
5367 return clang_getNullRange();
5368}
5369
5370void clang_enableStackTraces(void) {
5371 llvm::sys::PrintStackTraceOnErrorSignal();
5372}
5373
5374void clang_executeOnThread(void (*fn)(void*), void *user_data,
5375 unsigned stack_size) {
5376 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5377}
5378
5379} // end: extern "C"
5380
5381//===----------------------------------------------------------------------===//
5382// Token-based Operations.
5383//===----------------------------------------------------------------------===//
5384
5385/* CXToken layout:
5386 * int_data[0]: a CXTokenKind
5387 * int_data[1]: starting token location
5388 * int_data[2]: token length
5389 * int_data[3]: reserved
5390 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5391 * otherwise unused.
5392 */
5393extern "C" {
5394
5395CXTokenKind clang_getTokenKind(CXToken CXTok) {
5396 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5397}
5398
5399CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5400 switch (clang_getTokenKind(CXTok)) {
5401 case CXToken_Identifier:
5402 case CXToken_Keyword:
5403 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005404 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 ->getNameStart());
5406
5407 case CXToken_Literal: {
5408 // We have stashed the starting pointer in the ptr_data field. Use it.
5409 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005410 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 }
5412
5413 case CXToken_Punctuation:
5414 case CXToken_Comment:
5415 break;
5416 }
5417
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005418 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005419 LOG_BAD_TU(TU);
5420 return cxstring::createEmpty();
5421 }
5422
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 // We have to find the starting buffer pointer the hard way, by
5424 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005425 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005427 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005428
5429 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5430 std::pair<FileID, unsigned> LocInfo
5431 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5432 bool Invalid = false;
5433 StringRef Buffer
5434 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5435 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005436 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005437
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005438 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005439}
5440
5441CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005442 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005443 LOG_BAD_TU(TU);
5444 return clang_getNullLocation();
5445 }
5446
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005447 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 if (!CXXUnit)
5449 return clang_getNullLocation();
5450
5451 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5452 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5453}
5454
5455CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005456 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005457 LOG_BAD_TU(TU);
5458 return clang_getNullRange();
5459 }
5460
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005461 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 if (!CXXUnit)
5463 return clang_getNullRange();
5464
5465 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5466 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5467}
5468
5469static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5470 SmallVectorImpl<CXToken> &CXTokens) {
5471 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5472 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005473 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005475 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005476
5477 // Cannot tokenize across files.
5478 if (BeginLocInfo.first != EndLocInfo.first)
5479 return;
5480
5481 // Create a lexer
5482 bool Invalid = false;
5483 StringRef Buffer
5484 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5485 if (Invalid)
5486 return;
5487
5488 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5489 CXXUnit->getASTContext().getLangOpts(),
5490 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5491 Lex.SetCommentRetentionState(true);
5492
5493 // Lex tokens until we hit the end of the range.
5494 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5495 Token Tok;
5496 bool previousWasAt = false;
5497 do {
5498 // Lex the next token
5499 Lex.LexFromRawLexer(Tok);
5500 if (Tok.is(tok::eof))
5501 break;
5502
5503 // Initialize the CXToken.
5504 CXToken CXTok;
5505
5506 // - Common fields
5507 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5508 CXTok.int_data[2] = Tok.getLength();
5509 CXTok.int_data[3] = 0;
5510
5511 // - Kind-specific fields
5512 if (Tok.isLiteral()) {
5513 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005514 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 } else if (Tok.is(tok::raw_identifier)) {
5516 // Lookup the identifier to determine whether we have a keyword.
5517 IdentifierInfo *II
5518 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5519
5520 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5521 CXTok.int_data[0] = CXToken_Keyword;
5522 }
5523 else {
5524 CXTok.int_data[0] = Tok.is(tok::identifier)
5525 ? CXToken_Identifier
5526 : CXToken_Keyword;
5527 }
5528 CXTok.ptr_data = II;
5529 } else if (Tok.is(tok::comment)) {
5530 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005531 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 } else {
5533 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005534 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 }
5536 CXTokens.push_back(CXTok);
5537 previousWasAt = Tok.is(tok::at);
5538 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5539}
5540
5541void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5542 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005543 LOG_FUNC_SECTION {
5544 *Log << TU << ' ' << Range;
5545 }
5546
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005548 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 if (NumTokens)
5550 *NumTokens = 0;
5551
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005552 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005553 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005554 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005555 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005556
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005557 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 if (!CXXUnit || !Tokens || !NumTokens)
5559 return;
5560
5561 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5562
5563 SourceRange R = cxloc::translateCXSourceRange(Range);
5564 if (R.isInvalid())
5565 return;
5566
5567 SmallVector<CXToken, 32> CXTokens;
5568 getTokens(CXXUnit, R, CXTokens);
5569
5570 if (CXTokens.empty())
5571 return;
5572
5573 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5574 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5575 *NumTokens = CXTokens.size();
5576}
5577
5578void clang_disposeTokens(CXTranslationUnit TU,
5579 CXToken *Tokens, unsigned NumTokens) {
5580 free(Tokens);
5581}
5582
5583} // end: extern "C"
5584
5585//===----------------------------------------------------------------------===//
5586// Token annotation APIs.
5587//===----------------------------------------------------------------------===//
5588
Guy Benyei11169dd2012-12-18 14:30:41 +00005589static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5590 CXCursor parent,
5591 CXClientData client_data);
5592static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5593 CXClientData client_data);
5594
5595namespace {
5596class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 CXToken *Tokens;
5598 CXCursor *Cursors;
5599 unsigned NumTokens;
5600 unsigned TokIdx;
5601 unsigned PreprocessingTokIdx;
5602 CursorVisitor AnnotateVis;
5603 SourceManager &SrcMgr;
5604 bool HasContextSensitiveKeywords;
5605
5606 struct PostChildrenInfo {
5607 CXCursor Cursor;
5608 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005609 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 unsigned BeforeChildrenTokenIdx;
5611 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005612 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005613
5614 CXToken &getTok(unsigned Idx) {
5615 assert(Idx < NumTokens);
5616 return Tokens[Idx];
5617 }
5618 const CXToken &getTok(unsigned Idx) const {
5619 assert(Idx < NumTokens);
5620 return Tokens[Idx];
5621 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 bool MoreTokens() const { return TokIdx < NumTokens; }
5623 unsigned NextToken() const { return TokIdx; }
5624 void AdvanceToken() { ++TokIdx; }
5625 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005626 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 }
5628 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005629 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 }
5631 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005632 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 }
5634
5635 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005636 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 SourceRange);
5638
5639public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005640 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005641 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005642 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005644 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 AnnotateTokensVisitor, this,
5646 /*VisitPreprocessorLast=*/true,
5647 /*VisitIncludedEntities=*/false,
5648 RegionOfInterest,
5649 /*VisitDeclsOnly=*/false,
5650 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005651 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 HasContextSensitiveKeywords(false) { }
5653
5654 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5655 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5656 bool postVisitChildren(CXCursor cursor);
5657 void AnnotateTokens();
5658
5659 /// \brief Determine whether the annotator saw any cursors that have
5660 /// context-sensitive keywords.
5661 bool hasContextSensitiveKeywords() const {
5662 return HasContextSensitiveKeywords;
5663 }
5664
5665 ~AnnotateTokensWorker() {
5666 assert(PostChildrenInfos.empty());
5667 }
5668};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005669}
Guy Benyei11169dd2012-12-18 14:30:41 +00005670
5671void AnnotateTokensWorker::AnnotateTokens() {
5672 // Walk the AST within the region of interest, annotating tokens
5673 // along the way.
5674 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675}
Guy Benyei11169dd2012-12-18 14:30:41 +00005676
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005677static inline void updateCursorAnnotation(CXCursor &Cursor,
5678 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005679 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005681 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005682}
5683
5684/// \brief It annotates and advances tokens with a cursor until the comparison
5685//// between the cursor location and the source range is the same as
5686/// \arg compResult.
5687///
5688/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5689/// Pass RangeOverlap to annotate tokens inside a range.
5690void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5691 RangeComparisonResult compResult,
5692 SourceRange range) {
5693 while (MoreTokens()) {
5694 const unsigned I = NextToken();
5695 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005696 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5697 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005698
5699 SourceLocation TokLoc = GetTokenLoc(I);
5700 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005701 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 AdvanceToken();
5703 continue;
5704 }
5705 break;
5706 }
5707}
5708
5709/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005710/// \returns true if it advanced beyond all macro tokens, false otherwise.
5711bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 CXCursor updateC,
5713 RangeComparisonResult compResult,
5714 SourceRange range) {
5715 assert(MoreTokens());
5716 assert(isFunctionMacroToken(NextToken()) &&
5717 "Should be called only for macro arg tokens");
5718
5719 // This works differently than annotateAndAdvanceTokens; because expanded
5720 // macro arguments can have arbitrary translation-unit source order, we do not
5721 // advance the token index one by one until a token fails the range test.
5722 // We only advance once past all of the macro arg tokens if all of them
5723 // pass the range test. If one of them fails we keep the token index pointing
5724 // at the start of the macro arg tokens so that the failing token will be
5725 // annotated by a subsequent annotation try.
5726
5727 bool atLeastOneCompFail = false;
5728
5729 unsigned I = NextToken();
5730 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5731 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5732 if (TokLoc.isFileID())
5733 continue; // not macro arg token, it's parens or comma.
5734 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5735 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5736 Cursors[I] = updateC;
5737 } else
5738 atLeastOneCompFail = true;
5739 }
5740
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005741 if (atLeastOneCompFail)
5742 return false;
5743
5744 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5745 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005746}
5747
5748enum CXChildVisitResult
5749AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 SourceRange cursorRange = getRawCursorExtent(cursor);
5751 if (cursorRange.isInvalid())
5752 return CXChildVisit_Recurse;
5753
5754 if (!HasContextSensitiveKeywords) {
5755 // Objective-C properties can have context-sensitive keywords.
5756 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005757 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5759 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5760 }
5761 // Objective-C methods can have context-sensitive keywords.
5762 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5763 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005764 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5766 if (Method->getObjCDeclQualifier())
5767 HasContextSensitiveKeywords = true;
5768 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005769 for (const auto *P : Method->params()) {
5770 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 HasContextSensitiveKeywords = true;
5772 break;
5773 }
5774 }
5775 }
5776 }
5777 }
5778 // C++ methods can have context-sensitive keywords.
5779 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005780 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5782 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5783 HasContextSensitiveKeywords = true;
5784 }
5785 }
5786 // C++ classes can have context-sensitive keywords.
5787 else if (cursor.kind == CXCursor_StructDecl ||
5788 cursor.kind == CXCursor_ClassDecl ||
5789 cursor.kind == CXCursor_ClassTemplate ||
5790 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005791 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 if (D->hasAttr<FinalAttr>())
5793 HasContextSensitiveKeywords = true;
5794 }
5795 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005796
5797 // Don't override a property annotation with its getter/setter method.
5798 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5799 parent.kind == CXCursor_ObjCPropertyDecl)
5800 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005801
5802 if (clang_isPreprocessing(cursor.kind)) {
5803 // Items in the preprocessing record are kept separate from items in
5804 // declarations, so we keep a separate token index.
5805 unsigned SavedTokIdx = TokIdx;
5806 TokIdx = PreprocessingTokIdx;
5807
5808 // Skip tokens up until we catch up to the beginning of the preprocessing
5809 // entry.
5810 while (MoreTokens()) {
5811 const unsigned I = NextToken();
5812 SourceLocation TokLoc = GetTokenLoc(I);
5813 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5814 case RangeBefore:
5815 AdvanceToken();
5816 continue;
5817 case RangeAfter:
5818 case RangeOverlap:
5819 break;
5820 }
5821 break;
5822 }
5823
5824 // Look at all of the tokens within this range.
5825 while (MoreTokens()) {
5826 const unsigned I = NextToken();
5827 SourceLocation TokLoc = GetTokenLoc(I);
5828 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5829 case RangeBefore:
5830 llvm_unreachable("Infeasible");
5831 case RangeAfter:
5832 break;
5833 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005834 // For macro expansions, just note where the beginning of the macro
5835 // expansion occurs.
5836 if (cursor.kind == CXCursor_MacroExpansion) {
5837 if (TokLoc == cursorRange.getBegin())
5838 Cursors[I] = cursor;
5839 AdvanceToken();
5840 break;
5841 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005842 // We may have already annotated macro names inside macro definitions.
5843 if (Cursors[I].kind != CXCursor_MacroExpansion)
5844 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 continue;
5847 }
5848 break;
5849 }
5850
5851 // Save the preprocessing token index; restore the non-preprocessing
5852 // token index.
5853 PreprocessingTokIdx = TokIdx;
5854 TokIdx = SavedTokIdx;
5855 return CXChildVisit_Recurse;
5856 }
5857
5858 if (cursorRange.isInvalid())
5859 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005860
5861 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 const enum CXCursorKind K = clang_getCursorKind(parent);
5864 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005865 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5866 // Attributes are annotated out-of-order, skip tokens until we reach it.
5867 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 ? clang_getNullCursor() : parent;
5869
5870 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5871
5872 // Avoid having the cursor of an expression "overwrite" the annotation of the
5873 // variable declaration that it belongs to.
5874 // This can happen for C++ constructor expressions whose range generally
5875 // include the variable declaration, e.g.:
5876 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005877 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005878 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005879 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 const unsigned I = NextToken();
5881 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5882 E->getLocStart() == D->getLocation() &&
5883 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005884 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 AdvanceToken();
5886 }
5887 }
5888 }
5889
5890 // Before recursing into the children keep some state that we are going
5891 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5892 // extra work after the child nodes are visited.
5893 // Note that we don't call VisitChildren here to avoid traversing statements
5894 // code-recursively which can blow the stack.
5895
5896 PostChildrenInfo Info;
5897 Info.Cursor = cursor;
5898 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005899 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 Info.BeforeChildrenTokenIdx = NextToken();
5901 PostChildrenInfos.push_back(Info);
5902
5903 return CXChildVisit_Recurse;
5904}
5905
5906bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5907 if (PostChildrenInfos.empty())
5908 return false;
5909 const PostChildrenInfo &Info = PostChildrenInfos.back();
5910 if (!clang_equalCursors(Info.Cursor, cursor))
5911 return false;
5912
5913 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5914 const unsigned AfterChildren = NextToken();
5915 SourceRange cursorRange = Info.CursorRange;
5916
5917 // Scan the tokens that are at the end of the cursor, but are not captured
5918 // but the child cursors.
5919 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5920
5921 // Scan the tokens that are at the beginning of the cursor, but are not
5922 // capture by the child cursors.
5923 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5924 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5925 break;
5926
5927 Cursors[I] = cursor;
5928 }
5929
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005930 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5931 // encountered the attribute cursor.
5932 if (clang_isAttribute(cursor.kind))
5933 TokIdx = Info.BeforeReachingCursorIdx;
5934
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 PostChildrenInfos.pop_back();
5936 return false;
5937}
5938
5939static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5940 CXCursor parent,
5941 CXClientData client_data) {
5942 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5943}
5944
5945static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5946 CXClientData client_data) {
5947 return static_cast<AnnotateTokensWorker*>(client_data)->
5948 postVisitChildren(cursor);
5949}
5950
5951namespace {
5952
5953/// \brief Uses the macro expansions in the preprocessing record to find
5954/// and mark tokens that are macro arguments. This info is used by the
5955/// AnnotateTokensWorker.
5956class MarkMacroArgTokensVisitor {
5957 SourceManager &SM;
5958 CXToken *Tokens;
5959 unsigned NumTokens;
5960 unsigned CurIdx;
5961
5962public:
5963 MarkMacroArgTokensVisitor(SourceManager &SM,
5964 CXToken *tokens, unsigned numTokens)
5965 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5966
5967 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5968 if (cursor.kind != CXCursor_MacroExpansion)
5969 return CXChildVisit_Continue;
5970
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005971 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (macroRange.getBegin() == macroRange.getEnd())
5973 return CXChildVisit_Continue; // it's not a function macro.
5974
5975 for (; CurIdx < NumTokens; ++CurIdx) {
5976 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5977 macroRange.getBegin()))
5978 break;
5979 }
5980
5981 if (CurIdx == NumTokens)
5982 return CXChildVisit_Break;
5983
5984 for (; CurIdx < NumTokens; ++CurIdx) {
5985 SourceLocation tokLoc = getTokenLoc(CurIdx);
5986 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5987 break;
5988
5989 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5990 }
5991
5992 if (CurIdx == NumTokens)
5993 return CXChildVisit_Break;
5994
5995 return CXChildVisit_Continue;
5996 }
5997
5998private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005999 CXToken &getTok(unsigned Idx) {
6000 assert(Idx < NumTokens);
6001 return Tokens[Idx];
6002 }
6003 const CXToken &getTok(unsigned Idx) const {
6004 assert(Idx < NumTokens);
6005 return Tokens[Idx];
6006 }
6007
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006009 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 }
6011
6012 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6013 // The third field is reserved and currently not used. Use it here
6014 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006015 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 }
6017};
6018
6019} // end anonymous namespace
6020
6021static CXChildVisitResult
6022MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6023 CXClientData client_data) {
6024 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6025 parent);
6026}
6027
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006028/// \brief Used by \c annotatePreprocessorTokens.
6029/// \returns true if lexing was finished, false otherwise.
6030static bool lexNext(Lexer &Lex, Token &Tok,
6031 unsigned &NextIdx, unsigned NumTokens) {
6032 if (NextIdx >= NumTokens)
6033 return true;
6034
6035 ++NextIdx;
6036 Lex.LexFromRawLexer(Tok);
6037 if (Tok.is(tok::eof))
6038 return true;
6039
6040 return false;
6041}
6042
Guy Benyei11169dd2012-12-18 14:30:41 +00006043static void annotatePreprocessorTokens(CXTranslationUnit TU,
6044 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006045 CXCursor *Cursors,
6046 CXToken *Tokens,
6047 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006048 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006049
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006050 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6052 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006053 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006054 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006055 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006056
6057 if (BeginLocInfo.first != EndLocInfo.first)
6058 return;
6059
6060 StringRef Buffer;
6061 bool Invalid = false;
6062 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6063 if (Buffer.empty() || Invalid)
6064 return;
6065
6066 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6067 CXXUnit->getASTContext().getLangOpts(),
6068 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6069 Buffer.end());
6070 Lex.SetCommentRetentionState(true);
6071
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006072 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 // Lex tokens in raw mode until we hit the end of the range, to avoid
6074 // entering #includes or expanding macros.
6075 while (true) {
6076 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006077 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6078 break;
6079 unsigned TokIdx = NextIdx-1;
6080 assert(Tok.getLocation() ==
6081 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006082
6083 reprocess:
6084 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006085 // We have found a preprocessing directive. Annotate the tokens
6086 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 //
6088 // FIXME: Some simple tests here could identify macro definitions and
6089 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006090
6091 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006092 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6093 break;
6094
Craig Topper69186e72014-06-08 08:38:04 +00006095 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006096 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006097 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6098 break;
6099
6100 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006101 IdentifierInfo &II =
6102 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006103 SourceLocation MappedTokLoc =
6104 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6105 MI = getMacroInfo(II, MappedTokLoc, TU);
6106 }
6107 }
6108
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006109 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006111 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6112 finished = true;
6113 break;
6114 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006115 // If we are in a macro definition, check if the token was ever a
6116 // macro name and annotate it if that's the case.
6117 if (MI) {
6118 SourceLocation SaveLoc = Tok.getLocation();
6119 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006120 MacroDefinitionRecord *MacroDef =
6121 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006122 Tok.setLocation(SaveLoc);
6123 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006124 Cursors[NextIdx - 1] =
6125 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006126 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006127 } while (!Tok.isAtStartOfLine());
6128
6129 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6130 assert(TokIdx <= LastIdx);
6131 SourceLocation EndLoc =
6132 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6133 CXCursor Cursor =
6134 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6135
6136 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006137 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006138
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006139 if (finished)
6140 break;
6141 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 }
6144}
6145
6146// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006147static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6148 CXToken *Tokens, unsigned NumTokens,
6149 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006150 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6152 setThreadBackgroundPriority();
6153
6154 // Determine the region of interest, which contains all of the tokens.
6155 SourceRange RegionOfInterest;
6156 RegionOfInterest.setBegin(
6157 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6158 RegionOfInterest.setEnd(
6159 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6160 Tokens[NumTokens-1])));
6161
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 // Relex the tokens within the source range to look for preprocessing
6163 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006164 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006165
6166 // If begin location points inside a macro argument, set it to the expansion
6167 // location so we can have the full context when annotating semantically.
6168 {
6169 SourceManager &SM = CXXUnit->getSourceManager();
6170 SourceLocation Loc =
6171 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6172 if (Loc.isMacroID())
6173 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6174 }
6175
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6177 // Search and mark tokens that are macro argument expansions.
6178 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6179 Tokens, NumTokens);
6180 CursorVisitor MacroArgMarker(TU,
6181 MarkMacroArgTokensVisitorDelegate, &Visitor,
6182 /*VisitPreprocessorLast=*/true,
6183 /*VisitIncludedEntities=*/false,
6184 RegionOfInterest);
6185 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6186 }
6187
6188 // Annotate all of the source locations in the region of interest that map to
6189 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006190 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006191
6192 // FIXME: We use a ridiculous stack size here because the data-recursion
6193 // algorithm uses a large stack frame than the non-data recursive version,
6194 // and AnnotationTokensWorker currently transforms the data-recursion
6195 // algorithm back into a traditional recursion by explicitly calling
6196 // VisitChildren(). We will need to remove this explicit recursive call.
6197 W.AnnotateTokens();
6198
6199 // If we ran into any entities that involve context-sensitive keywords,
6200 // take another pass through the tokens to mark them as such.
6201 if (W.hasContextSensitiveKeywords()) {
6202 for (unsigned I = 0; I != NumTokens; ++I) {
6203 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6204 continue;
6205
6206 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6207 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006208 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006209 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6210 if (Property->getPropertyAttributesAsWritten() != 0 &&
6211 llvm::StringSwitch<bool>(II->getName())
6212 .Case("readonly", true)
6213 .Case("assign", true)
6214 .Case("unsafe_unretained", true)
6215 .Case("readwrite", true)
6216 .Case("retain", true)
6217 .Case("copy", true)
6218 .Case("nonatomic", true)
6219 .Case("atomic", true)
6220 .Case("getter", true)
6221 .Case("setter", true)
6222 .Case("strong", true)
6223 .Case("weak", true)
6224 .Default(false))
6225 Tokens[I].int_data[0] = CXToken_Keyword;
6226 }
6227 continue;
6228 }
6229
6230 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6231 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6232 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6233 if (llvm::StringSwitch<bool>(II->getName())
6234 .Case("in", true)
6235 .Case("out", true)
6236 .Case("inout", true)
6237 .Case("oneway", true)
6238 .Case("bycopy", true)
6239 .Case("byref", true)
6240 .Default(false))
6241 Tokens[I].int_data[0] = CXToken_Keyword;
6242 continue;
6243 }
6244
6245 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6246 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6247 Tokens[I].int_data[0] = CXToken_Keyword;
6248 continue;
6249 }
6250 }
6251 }
6252}
6253
6254extern "C" {
6255
6256void clang_annotateTokens(CXTranslationUnit TU,
6257 CXToken *Tokens, unsigned NumTokens,
6258 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006259 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006260 LOG_BAD_TU(TU);
6261 return;
6262 }
6263 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006264 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006265 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006266 }
6267
6268 LOG_FUNC_SECTION {
6269 *Log << TU << ' ';
6270 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6271 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6272 *Log << clang_getRange(bloc, eloc);
6273 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006274
6275 // Any token we don't specifically annotate will have a NULL cursor.
6276 CXCursor C = clang_getNullCursor();
6277 for (unsigned I = 0; I != NumTokens; ++I)
6278 Cursors[I] = C;
6279
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006280 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006281 if (!CXXUnit)
6282 return;
6283
6284 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006285
6286 auto AnnotateTokensImpl = [=]() {
6287 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6288 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006289 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006290 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6292 }
6293}
6294
6295} // end: extern "C"
6296
6297//===----------------------------------------------------------------------===//
6298// Operations for querying linkage of a cursor.
6299//===----------------------------------------------------------------------===//
6300
6301extern "C" {
6302CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6303 if (!clang_isDeclaration(cursor.kind))
6304 return CXLinkage_Invalid;
6305
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006306 const Decl *D = cxcursor::getCursorDecl(cursor);
6307 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006308 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006309 case NoLinkage:
6310 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 case InternalLinkage: return CXLinkage_Internal;
6312 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6313 case ExternalLinkage: return CXLinkage_External;
6314 };
6315
6316 return CXLinkage_Invalid;
6317}
6318} // end: extern "C"
6319
6320//===----------------------------------------------------------------------===//
6321// Operations for querying language of a cursor.
6322//===----------------------------------------------------------------------===//
6323
6324static CXLanguageKind getDeclLanguage(const Decl *D) {
6325 if (!D)
6326 return CXLanguage_C;
6327
6328 switch (D->getKind()) {
6329 default:
6330 break;
6331 case Decl::ImplicitParam:
6332 case Decl::ObjCAtDefsField:
6333 case Decl::ObjCCategory:
6334 case Decl::ObjCCategoryImpl:
6335 case Decl::ObjCCompatibleAlias:
6336 case Decl::ObjCImplementation:
6337 case Decl::ObjCInterface:
6338 case Decl::ObjCIvar:
6339 case Decl::ObjCMethod:
6340 case Decl::ObjCProperty:
6341 case Decl::ObjCPropertyImpl:
6342 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006343 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 return CXLanguage_ObjC;
6345 case Decl::CXXConstructor:
6346 case Decl::CXXConversion:
6347 case Decl::CXXDestructor:
6348 case Decl::CXXMethod:
6349 case Decl::CXXRecord:
6350 case Decl::ClassTemplate:
6351 case Decl::ClassTemplatePartialSpecialization:
6352 case Decl::ClassTemplateSpecialization:
6353 case Decl::Friend:
6354 case Decl::FriendTemplate:
6355 case Decl::FunctionTemplate:
6356 case Decl::LinkageSpec:
6357 case Decl::Namespace:
6358 case Decl::NamespaceAlias:
6359 case Decl::NonTypeTemplateParm:
6360 case Decl::StaticAssert:
6361 case Decl::TemplateTemplateParm:
6362 case Decl::TemplateTypeParm:
6363 case Decl::UnresolvedUsingTypename:
6364 case Decl::UnresolvedUsingValue:
6365 case Decl::Using:
6366 case Decl::UsingDirective:
6367 case Decl::UsingShadow:
6368 return CXLanguage_CPlusPlus;
6369 }
6370
6371 return CXLanguage_C;
6372}
6373
6374extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006375
6376static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6377 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6378 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006379
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006380 switch (D->getAvailability()) {
6381 case AR_Available:
6382 case AR_NotYetIntroduced:
6383 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006384 return getCursorAvailabilityForDecl(
6385 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006386 return CXAvailability_Available;
6387
6388 case AR_Deprecated:
6389 return CXAvailability_Deprecated;
6390
6391 case AR_Unavailable:
6392 return CXAvailability_NotAvailable;
6393 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006394
6395 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006396}
6397
Guy Benyei11169dd2012-12-18 14:30:41 +00006398enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6399 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006400 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6401 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006402
6403 return CXAvailability_Available;
6404}
6405
6406static CXVersion convertVersion(VersionTuple In) {
6407 CXVersion Out = { -1, -1, -1 };
6408 if (In.empty())
6409 return Out;
6410
6411 Out.Major = In.getMajor();
6412
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006413 Optional<unsigned> Minor = In.getMinor();
6414 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 Out.Minor = *Minor;
6416 else
6417 return Out;
6418
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006419 Optional<unsigned> Subminor = In.getSubminor();
6420 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 Out.Subminor = *Subminor;
6422
6423 return Out;
6424}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006425
6426static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6427 int *always_deprecated,
6428 CXString *deprecated_message,
6429 int *always_unavailable,
6430 CXString *unavailable_message,
6431 CXPlatformAvailability *availability,
6432 int availability_size) {
6433 bool HadAvailAttr = false;
6434 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006435 for (auto A : D->attrs()) {
6436 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006437 HadAvailAttr = true;
6438 if (always_deprecated)
6439 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006440 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006441 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006442 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006443 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006444 continue;
6445 }
6446
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006447 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006448 HadAvailAttr = true;
6449 if (always_unavailable)
6450 *always_unavailable = 1;
6451 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006452 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006453 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6454 }
6455 continue;
6456 }
6457
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006458 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006459 HadAvailAttr = true;
6460 if (N < availability_size) {
6461 availability[N].Platform
6462 = cxstring::createDup(Avail->getPlatform()->getName());
6463 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6464 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6465 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6466 availability[N].Unavailable = Avail->getUnavailable();
6467 availability[N].Message = cxstring::createDup(Avail->getMessage());
6468 }
6469 ++N;
6470 }
6471 }
6472
6473 if (!HadAvailAttr)
6474 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6475 return getCursorPlatformAvailabilityForDecl(
6476 cast<Decl>(EnumConst->getDeclContext()),
6477 always_deprecated,
6478 deprecated_message,
6479 always_unavailable,
6480 unavailable_message,
6481 availability,
6482 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006483
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006484 return N;
6485}
6486
Guy Benyei11169dd2012-12-18 14:30:41 +00006487int clang_getCursorPlatformAvailability(CXCursor cursor,
6488 int *always_deprecated,
6489 CXString *deprecated_message,
6490 int *always_unavailable,
6491 CXString *unavailable_message,
6492 CXPlatformAvailability *availability,
6493 int availability_size) {
6494 if (always_deprecated)
6495 *always_deprecated = 0;
6496 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006497 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 if (always_unavailable)
6499 *always_unavailable = 0;
6500 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006501 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006502
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 if (!clang_isDeclaration(cursor.kind))
6504 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006505
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006506 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 if (!D)
6508 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006509
6510 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6511 deprecated_message,
6512 always_unavailable,
6513 unavailable_message,
6514 availability,
6515 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006516}
6517
6518void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6519 clang_disposeString(availability->Platform);
6520 clang_disposeString(availability->Message);
6521}
6522
6523CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6524 if (clang_isDeclaration(cursor.kind))
6525 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6526
6527 return CXLanguage_Invalid;
6528}
6529
6530 /// \brief If the given cursor is the "templated" declaration
6531 /// descibing a class or function template, return the class or
6532 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006533static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006534 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006535 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006537 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6539 return FunTmpl;
6540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006541 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006542 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6543 return ClassTmpl;
6544
6545 return D;
6546}
6547
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006548
6549enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6550 StorageClass sc = SC_None;
6551 const Decl *D = getCursorDecl(C);
6552 if (D) {
6553 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6554 sc = FD->getStorageClass();
6555 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6556 sc = VD->getStorageClass();
6557 } else {
6558 return CX_SC_Invalid;
6559 }
6560 } else {
6561 return CX_SC_Invalid;
6562 }
6563 switch (sc) {
6564 case SC_None:
6565 return CX_SC_None;
6566 case SC_Extern:
6567 return CX_SC_Extern;
6568 case SC_Static:
6569 return CX_SC_Static;
6570 case SC_PrivateExtern:
6571 return CX_SC_PrivateExtern;
6572 case SC_OpenCLWorkGroupLocal:
6573 return CX_SC_OpenCLWorkGroupLocal;
6574 case SC_Auto:
6575 return CX_SC_Auto;
6576 case SC_Register:
6577 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006578 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006579 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006580}
6581
Guy Benyei11169dd2012-12-18 14:30:41 +00006582CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6583 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006584 if (const Decl *D = getCursorDecl(cursor)) {
6585 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 if (!DC)
6587 return clang_getNullCursor();
6588
6589 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6590 getCursorTU(cursor));
6591 }
6592 }
6593
6594 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006595 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 return MakeCXCursor(D, getCursorTU(cursor));
6597 }
6598
6599 return clang_getNullCursor();
6600}
6601
6602CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6603 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006604 if (const Decl *D = getCursorDecl(cursor)) {
6605 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006606 if (!DC)
6607 return clang_getNullCursor();
6608
6609 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6610 getCursorTU(cursor));
6611 }
6612 }
6613
6614 // FIXME: Note that we can't easily compute the lexical context of a
6615 // statement or expression, so we return nothing.
6616 return clang_getNullCursor();
6617}
6618
6619CXFile clang_getIncludedFile(CXCursor cursor) {
6620 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006621 return nullptr;
6622
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006623 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006624 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006625}
6626
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006627unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6628 if (C.kind != CXCursor_ObjCPropertyDecl)
6629 return CXObjCPropertyAttr_noattr;
6630
6631 unsigned Result = CXObjCPropertyAttr_noattr;
6632 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6633 ObjCPropertyDecl::PropertyAttributeKind Attr =
6634 PD->getPropertyAttributesAsWritten();
6635
6636#define SET_CXOBJCPROP_ATTR(A) \
6637 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6638 Result |= CXObjCPropertyAttr_##A
6639 SET_CXOBJCPROP_ATTR(readonly);
6640 SET_CXOBJCPROP_ATTR(getter);
6641 SET_CXOBJCPROP_ATTR(assign);
6642 SET_CXOBJCPROP_ATTR(readwrite);
6643 SET_CXOBJCPROP_ATTR(retain);
6644 SET_CXOBJCPROP_ATTR(copy);
6645 SET_CXOBJCPROP_ATTR(nonatomic);
6646 SET_CXOBJCPROP_ATTR(setter);
6647 SET_CXOBJCPROP_ATTR(atomic);
6648 SET_CXOBJCPROP_ATTR(weak);
6649 SET_CXOBJCPROP_ATTR(strong);
6650 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6651#undef SET_CXOBJCPROP_ATTR
6652
6653 return Result;
6654}
6655
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006656unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6657 if (!clang_isDeclaration(C.kind))
6658 return CXObjCDeclQualifier_None;
6659
6660 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6661 const Decl *D = getCursorDecl(C);
6662 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6663 QT = MD->getObjCDeclQualifier();
6664 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6665 QT = PD->getObjCDeclQualifier();
6666 if (QT == Decl::OBJC_TQ_None)
6667 return CXObjCDeclQualifier_None;
6668
6669 unsigned Result = CXObjCDeclQualifier_None;
6670 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6671 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6672 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6673 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6674 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6675 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6676
6677 return Result;
6678}
6679
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006680unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6681 if (!clang_isDeclaration(C.kind))
6682 return 0;
6683
6684 const Decl *D = getCursorDecl(C);
6685 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6686 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6687 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6688 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6689
6690 return 0;
6691}
6692
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006693unsigned clang_Cursor_isVariadic(CXCursor C) {
6694 if (!clang_isDeclaration(C.kind))
6695 return 0;
6696
6697 const Decl *D = getCursorDecl(C);
6698 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6699 return FD->isVariadic();
6700 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6701 return MD->isVariadic();
6702
6703 return 0;
6704}
6705
Guy Benyei11169dd2012-12-18 14:30:41 +00006706CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6707 if (!clang_isDeclaration(C.kind))
6708 return clang_getNullRange();
6709
6710 const Decl *D = getCursorDecl(C);
6711 ASTContext &Context = getCursorContext(C);
6712 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6713 if (!RC)
6714 return clang_getNullRange();
6715
6716 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6717}
6718
6719CXString clang_Cursor_getRawCommentText(CXCursor C) {
6720 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006721 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006722
6723 const Decl *D = getCursorDecl(C);
6724 ASTContext &Context = getCursorContext(C);
6725 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6726 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6727 StringRef();
6728
6729 // Don't duplicate the string because RawText points directly into source
6730 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006731 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006732}
6733
6734CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6735 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006736 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006737
6738 const Decl *D = getCursorDecl(C);
6739 const ASTContext &Context = getCursorContext(C);
6740 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6741
6742 if (RC) {
6743 StringRef BriefText = RC->getBriefText(Context);
6744
6745 // Don't duplicate the string because RawComment ensures that this memory
6746 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006747 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 }
6749
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006750 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006751}
6752
Guy Benyei11169dd2012-12-18 14:30:41 +00006753CXModule clang_Cursor_getModule(CXCursor C) {
6754 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006755 if (const ImportDecl *ImportD =
6756 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006757 return ImportD->getImportedModule();
6758 }
6759
Craig Topper69186e72014-06-08 08:38:04 +00006760 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006761}
6762
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006763CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6764 if (isNotUsableTU(TU)) {
6765 LOG_BAD_TU(TU);
6766 return nullptr;
6767 }
6768 if (!File)
6769 return nullptr;
6770 FileEntry *FE = static_cast<FileEntry *>(File);
6771
6772 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6773 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6774 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6775
Richard Smithfeb54b62014-10-23 02:01:19 +00006776 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006777}
6778
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006779CXFile clang_Module_getASTFile(CXModule CXMod) {
6780 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006781 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006782 Module *Mod = static_cast<Module*>(CXMod);
6783 return const_cast<FileEntry *>(Mod->getASTFile());
6784}
6785
Guy Benyei11169dd2012-12-18 14:30:41 +00006786CXModule clang_Module_getParent(CXModule CXMod) {
6787 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006788 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006789 Module *Mod = static_cast<Module*>(CXMod);
6790 return Mod->Parent;
6791}
6792
6793CXString clang_Module_getName(CXModule CXMod) {
6794 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006795 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006797 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006798}
6799
6800CXString clang_Module_getFullName(CXModule CXMod) {
6801 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006802 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006804 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006805}
6806
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006807int clang_Module_isSystem(CXModule CXMod) {
6808 if (!CXMod)
6809 return 0;
6810 Module *Mod = static_cast<Module*>(CXMod);
6811 return Mod->IsSystem;
6812}
6813
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006814unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6815 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006816 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006817 LOG_BAD_TU(TU);
6818 return 0;
6819 }
6820 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006821 return 0;
6822 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006823 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6824 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6825 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006826}
6827
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006828CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6829 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006830 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006831 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006832 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006833 }
6834 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006836 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006837 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006838
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006839 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6840 if (Index < TopHeaders.size())
6841 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006842
Craig Topper69186e72014-06-08 08:38:04 +00006843 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006844}
6845
6846} // end: extern "C"
6847
6848//===----------------------------------------------------------------------===//
6849// C++ AST instrospection.
6850//===----------------------------------------------------------------------===//
6851
6852extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006853unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6854 if (!clang_isDeclaration(C.kind))
6855 return 0;
6856
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006857 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006858 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006859 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006860 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6861}
6862
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006863unsigned clang_CXXMethod_isConst(CXCursor C) {
6864 if (!clang_isDeclaration(C.kind))
6865 return 0;
6866
6867 const Decl *D = cxcursor::getCursorDecl(C);
6868 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006869 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006870 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6871}
6872
Guy Benyei11169dd2012-12-18 14:30:41 +00006873unsigned clang_CXXMethod_isStatic(CXCursor C) {
6874 if (!clang_isDeclaration(C.kind))
6875 return 0;
6876
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006877 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006878 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006879 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006880 return (Method && Method->isStatic()) ? 1 : 0;
6881}
6882
6883unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6884 if (!clang_isDeclaration(C.kind))
6885 return 0;
6886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006887 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006888 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006889 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006890 return (Method && Method->isVirtual()) ? 1 : 0;
6891}
6892} // end: extern "C"
6893
6894//===----------------------------------------------------------------------===//
6895// Attribute introspection.
6896//===----------------------------------------------------------------------===//
6897
6898extern "C" {
6899CXType clang_getIBOutletCollectionType(CXCursor C) {
6900 if (C.kind != CXCursor_IBOutletCollectionAttr)
6901 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6902
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006903 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006904 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6905
6906 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6907}
6908} // end: extern "C"
6909
6910//===----------------------------------------------------------------------===//
6911// Inspecting memory usage.
6912//===----------------------------------------------------------------------===//
6913
6914typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6915
6916static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6917 enum CXTUResourceUsageKind k,
6918 unsigned long amount) {
6919 CXTUResourceUsageEntry entry = { k, amount };
6920 entries.push_back(entry);
6921}
6922
6923extern "C" {
6924
6925const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6926 const char *str = "";
6927 switch (kind) {
6928 case CXTUResourceUsage_AST:
6929 str = "ASTContext: expressions, declarations, and types";
6930 break;
6931 case CXTUResourceUsage_Identifiers:
6932 str = "ASTContext: identifiers";
6933 break;
6934 case CXTUResourceUsage_Selectors:
6935 str = "ASTContext: selectors";
6936 break;
6937 case CXTUResourceUsage_GlobalCompletionResults:
6938 str = "Code completion: cached global results";
6939 break;
6940 case CXTUResourceUsage_SourceManagerContentCache:
6941 str = "SourceManager: content cache allocator";
6942 break;
6943 case CXTUResourceUsage_AST_SideTables:
6944 str = "ASTContext: side tables";
6945 break;
6946 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6947 str = "SourceManager: malloc'ed memory buffers";
6948 break;
6949 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6950 str = "SourceManager: mmap'ed memory buffers";
6951 break;
6952 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6953 str = "ExternalASTSource: malloc'ed memory buffers";
6954 break;
6955 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6956 str = "ExternalASTSource: mmap'ed memory buffers";
6957 break;
6958 case CXTUResourceUsage_Preprocessor:
6959 str = "Preprocessor: malloc'ed memory";
6960 break;
6961 case CXTUResourceUsage_PreprocessingRecord:
6962 str = "Preprocessor: PreprocessingRecord";
6963 break;
6964 case CXTUResourceUsage_SourceManager_DataStructures:
6965 str = "SourceManager: data structures and tables";
6966 break;
6967 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6968 str = "Preprocessor: header search tables";
6969 break;
6970 }
6971 return str;
6972}
6973
6974CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006975 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006976 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006977 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006978 return usage;
6979 }
6980
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006981 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006982 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 ASTContext &astContext = astUnit->getASTContext();
6984
6985 // How much memory is used by AST nodes and types?
6986 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6987 (unsigned long) astContext.getASTAllocatedMemory());
6988
6989 // How much memory is used by identifiers?
6990 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6991 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6992
6993 // How much memory is used for selectors?
6994 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6995 (unsigned long) astContext.Selectors.getTotalMemory());
6996
6997 // How much memory is used by ASTContext's side tables?
6998 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6999 (unsigned long) astContext.getSideTableAllocatedMemory());
7000
7001 // How much memory is used for caching global code completion results?
7002 unsigned long completionBytes = 0;
7003 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007004 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007005 completionBytes = completionAllocator->getTotalMemory();
7006 }
7007 createCXTUResourceUsageEntry(*entries,
7008 CXTUResourceUsage_GlobalCompletionResults,
7009 completionBytes);
7010
7011 // How much memory is being used by SourceManager's content cache?
7012 createCXTUResourceUsageEntry(*entries,
7013 CXTUResourceUsage_SourceManagerContentCache,
7014 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7015
7016 // How much memory is being used by the MemoryBuffer's in SourceManager?
7017 const SourceManager::MemoryBufferSizes &srcBufs =
7018 astUnit->getSourceManager().getMemoryBufferSizes();
7019
7020 createCXTUResourceUsageEntry(*entries,
7021 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7022 (unsigned long) srcBufs.malloc_bytes);
7023 createCXTUResourceUsageEntry(*entries,
7024 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7025 (unsigned long) srcBufs.mmap_bytes);
7026 createCXTUResourceUsageEntry(*entries,
7027 CXTUResourceUsage_SourceManager_DataStructures,
7028 (unsigned long) astContext.getSourceManager()
7029 .getDataStructureSizes());
7030
7031 // How much memory is being used by the ExternalASTSource?
7032 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7033 const ExternalASTSource::MemoryBufferSizes &sizes =
7034 esrc->getMemoryBufferSizes();
7035
7036 createCXTUResourceUsageEntry(*entries,
7037 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7038 (unsigned long) sizes.malloc_bytes);
7039 createCXTUResourceUsageEntry(*entries,
7040 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7041 (unsigned long) sizes.mmap_bytes);
7042 }
7043
7044 // How much memory is being used by the Preprocessor?
7045 Preprocessor &pp = astUnit->getPreprocessor();
7046 createCXTUResourceUsageEntry(*entries,
7047 CXTUResourceUsage_Preprocessor,
7048 pp.getTotalMemory());
7049
7050 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7051 createCXTUResourceUsageEntry(*entries,
7052 CXTUResourceUsage_PreprocessingRecord,
7053 pRec->getTotalMemory());
7054 }
7055
7056 createCXTUResourceUsageEntry(*entries,
7057 CXTUResourceUsage_Preprocessor_HeaderSearch,
7058 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007059
Guy Benyei11169dd2012-12-18 14:30:41 +00007060 CXTUResourceUsage usage = { (void*) entries.get(),
7061 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007062 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007063 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007064 return usage;
7065}
7066
7067void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7068 if (usage.data)
7069 delete (MemUsageEntries*) usage.data;
7070}
7071
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007072CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7073 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007074 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007075 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007076
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007077 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007078 LOG_BAD_TU(TU);
7079 return skipped;
7080 }
7081
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007082 if (!file)
7083 return skipped;
7084
7085 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7086 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7087 if (!ppRec)
7088 return skipped;
7089
7090 ASTContext &Ctx = astUnit->getASTContext();
7091 SourceManager &sm = Ctx.getSourceManager();
7092 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7093 FileID wantedFileID = sm.translateFile(fileEntry);
7094
7095 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7096 std::vector<SourceRange> wantedRanges;
7097 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7098 i != ei; ++i) {
7099 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7100 wantedRanges.push_back(*i);
7101 }
7102
7103 skipped->count = wantedRanges.size();
7104 skipped->ranges = new CXSourceRange[skipped->count];
7105 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7106 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7107
7108 return skipped;
7109}
7110
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007111void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7112 if (ranges) {
7113 delete[] ranges->ranges;
7114 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007115 }
7116}
7117
Guy Benyei11169dd2012-12-18 14:30:41 +00007118} // end extern "C"
7119
7120void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7121 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7122 for (unsigned I = 0; I != Usage.numEntries; ++I)
7123 fprintf(stderr, " %s: %lu\n",
7124 clang_getTUResourceUsageName(Usage.entries[I].kind),
7125 Usage.entries[I].amount);
7126
7127 clang_disposeCXTUResourceUsage(Usage);
7128}
7129
7130//===----------------------------------------------------------------------===//
7131// Misc. utility functions.
7132//===----------------------------------------------------------------------===//
7133
7134/// Default to using an 8 MB stack size on "safety" threads.
7135static unsigned SafetyStackThreadSize = 8 << 20;
7136
7137namespace clang {
7138
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007139bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007140 unsigned Size) {
7141 if (!Size)
7142 Size = GetSafetyThreadStackSize();
7143 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007144 return CRC.RunSafelyOnThread(Fn, Size);
7145 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007146}
7147
7148unsigned GetSafetyThreadStackSize() {
7149 return SafetyStackThreadSize;
7150}
7151
7152void SetSafetyThreadStackSize(unsigned Value) {
7153 SafetyStackThreadSize = Value;
7154}
7155
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007156}
Guy Benyei11169dd2012-12-18 14:30:41 +00007157
7158void clang::setThreadBackgroundPriority() {
7159 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7160 return;
7161
Alp Toker1a86ad22014-07-06 06:24:00 +00007162#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7164#endif
7165}
7166
7167void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7168 if (!Unit)
7169 return;
7170
7171 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7172 DEnd = Unit->stored_diag_end();
7173 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007174 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007175 CXString Msg = clang_formatDiagnostic(&Diag,
7176 clang_defaultDiagnosticDisplayOptions());
7177 fprintf(stderr, "%s\n", clang_getCString(Msg));
7178 clang_disposeString(Msg);
7179 }
7180#ifdef LLVM_ON_WIN32
7181 // On Windows, force a flush, since there may be multiple copies of
7182 // stderr and stdout in the file system, all with different buffers
7183 // but writing to the same device.
7184 fflush(stderr);
7185#endif
7186}
7187
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7189 SourceLocation MacroDefLoc,
7190 CXTranslationUnit TU){
7191 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007192 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007193 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007194 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007195
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007196 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007197 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007198 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007199 if (MD) {
7200 for (MacroDirective::DefInfo
7201 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7202 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7203 return Def.getMacroInfo();
7204 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007205 }
7206
Craig Topper69186e72014-06-08 08:38:04 +00007207 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007208}
7209
Richard Smith66a81862015-05-04 02:25:31 +00007210const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007211 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007212 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007213 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007214 const IdentifierInfo *II = MacroDef->getName();
7215 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007216 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217
7218 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7219}
7220
Richard Smith66a81862015-05-04 02:25:31 +00007221MacroDefinitionRecord *
7222cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7223 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007225 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007226 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007227 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007228
7229 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007230 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7232 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007233 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234
7235 // Check that the token is inside the definition and not its argument list.
7236 SourceManager &SM = Unit->getSourceManager();
7237 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007238 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007239 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007240 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241
7242 Preprocessor &PP = Unit->getPreprocessor();
7243 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7244 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007245 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007246
Alp Toker2d57cea2014-05-17 04:53:25 +00007247 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007248 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007249 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007250
7251 // Check that the identifier is not one of the macro arguments.
7252 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007253 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007254
Richard Smith20e883e2015-04-29 23:20:19 +00007255 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007256 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007257 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007258
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007259 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007260}
7261
Richard Smith66a81862015-05-04 02:25:31 +00007262MacroDefinitionRecord *
7263cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7264 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007265 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007266 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007267
7268 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007270 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007271 Preprocessor &PP = Unit->getPreprocessor();
7272 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007273 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007274 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7275 Token Tok;
7276 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007277 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278
7279 return checkForMacroInMacroDefinition(MI, Tok, TU);
7280}
7281
Guy Benyei11169dd2012-12-18 14:30:41 +00007282extern "C" {
7283
7284CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007285 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007286}
7287
7288} // end: extern "C"
7289
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007290Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7291 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007292 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007293 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007294 if (Unit->isMainFileAST())
7295 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007296 return *this;
7297 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007298 } else {
7299 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007300 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007301 return *this;
7302}
7303
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007304Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7305 *this << FE->getName();
7306 return *this;
7307}
7308
7309Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7310 CXString cursorName = clang_getCursorDisplayName(cursor);
7311 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7312 clang_disposeString(cursorName);
7313 return *this;
7314}
7315
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007316Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7317 CXFile File;
7318 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007319 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007320 CXString FileName = clang_getFileName(File);
7321 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7322 clang_disposeString(FileName);
7323 return *this;
7324}
7325
7326Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7327 CXSourceLocation BLoc = clang_getRangeStart(range);
7328 CXSourceLocation ELoc = clang_getRangeEnd(range);
7329
7330 CXFile BFile;
7331 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007332 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007333
7334 CXFile EFile;
7335 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007336 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007337
7338 CXString BFileName = clang_getFileName(BFile);
7339 if (BFile == EFile) {
7340 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7341 BLine, BColumn, ELine, EColumn);
7342 } else {
7343 CXString EFileName = clang_getFileName(EFile);
7344 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7345 BLine, BColumn)
7346 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7347 ELine, EColumn);
7348 clang_disposeString(EFileName);
7349 }
7350 clang_disposeString(BFileName);
7351 return *this;
7352}
7353
7354Logger &cxindex::Logger::operator<<(CXString Str) {
7355 *this << clang_getCString(Str);
7356 return *this;
7357}
7358
7359Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7360 LogOS << Fmt;
7361 return *this;
7362}
7363
Chandler Carruth37ad2582014-06-27 15:14:39 +00007364static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7365
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007366cxindex::Logger::~Logger() {
7367 LogOS.flush();
7368
Chandler Carruth37ad2582014-06-27 15:14:39 +00007369 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007370
7371 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7372
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007373 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007374 OS << "[libclang:" << Name << ':';
7375
Alp Toker1a86ad22014-07-06 06:24:00 +00007376#ifdef USE_DARWIN_THREADS
7377 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007378 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7379 OS << tid << ':';
7380#endif
7381
7382 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7383 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007384 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007385
7386 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007387 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007388 OS << "--------------------------------------------------\n";
7389 }
7390}