blob: 347b377e23c51d31df806c59d2358214d5c48d77 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
150 if (R.isTokenRange() && !EndLoc.isInvalid()) {
151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000920bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
921 // Visit the bound, if it's explicit.
922 if (D->hasExplicitBound()) {
923 if (auto TInfo = D->getTypeSourceInfo()) {
924 if (Visit(TInfo->getTypeLoc()))
925 return true;
926 }
927 }
928
929 return false;
930}
931
Guy Benyei11169dd2012-12-18 14:30:41 +0000932bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000933 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000934 if (Visit(TSInfo->getTypeLoc()))
935 return true;
936
Aaron Ballman43b68be2014-03-07 17:50:17 +0000937 for (const auto *P : ND->params()) {
938 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000939 return true;
940 }
941
942 if (ND->isThisDeclarationADefinition() &&
943 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
944 return true;
945
946 return false;
947}
948
949template <typename DeclIt>
950static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
951 SourceManager &SM, SourceLocation EndLoc,
952 SmallVectorImpl<Decl *> &Decls) {
953 DeclIt next = *DI_current;
954 while (++next != DE_current) {
955 Decl *D_next = *next;
956 if (!D_next)
957 break;
958 SourceLocation L = D_next->getLocStart();
959 if (!L.isValid())
960 break;
961 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
962 *DI_current = next;
963 Decls.push_back(D_next);
964 continue;
965 }
966 break;
967 }
968}
969
Guy Benyei11169dd2012-12-18 14:30:41 +0000970bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
971 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
972 // an @implementation can lexically contain Decls that are not properly
973 // nested in the AST. When we identify such cases, we need to retrofit
974 // this nesting here.
975 if (!DI_current && !FileDI_current)
976 return VisitDeclContext(D);
977
978 // Scan the Decls that immediately come after the container
979 // in the current DeclContext. If any fall within the
980 // container's lexical region, stash them into a vector
981 // for later processing.
982 SmallVector<Decl *, 24> DeclsInContainer;
983 SourceLocation EndLoc = D->getSourceRange().getEnd();
984 SourceManager &SM = AU->getSourceManager();
985 if (EndLoc.isValid()) {
986 if (DI_current) {
987 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
988 DeclsInContainer);
989 } else {
990 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
991 DeclsInContainer);
992 }
993 }
994
995 // The common case.
996 if (DeclsInContainer.empty())
997 return VisitDeclContext(D);
998
999 // Get all the Decls in the DeclContext, and sort them with the
1000 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001001 for (auto *SubDecl : D->decls()) {
1002 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1003 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001005 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 }
1007
1008 // Now sort the Decls so that they appear in lexical order.
1009 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001010 [&SM](Decl *A, Decl *B) {
1011 SourceLocation L_A = A->getLocStart();
1012 SourceLocation L_B = B->getLocStart();
1013 assert(L_A.isValid() && L_B.isValid());
1014 return SM.isBeforeInTranslationUnit(L_A, L_B);
1015 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001016
1017 // Now visit the decls.
1018 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1019 E = DeclsInContainer.end(); I != E; ++I) {
1020 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001021 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001022 if (!V.hasValue())
1023 continue;
1024 if (!V.getValue())
1025 return false;
1026 if (Visit(Cursor, true))
1027 return true;
1028 }
1029 return false;
1030}
1031
1032bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1033 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1034 TU)))
1035 return true;
1036
Douglas Gregore9d95f12015-07-07 03:57:35 +00001037 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1038 return true;
1039
Guy Benyei11169dd2012-12-18 14:30:41 +00001040 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1041 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1042 E = ND->protocol_end(); I != E; ++I, ++PL)
1043 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1044 return true;
1045
1046 return VisitObjCContainerDecl(ND);
1047}
1048
1049bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1050 if (!PID->isThisDeclarationADefinition())
1051 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1052
1053 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1054 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1055 E = PID->protocol_end(); I != E; ++I, ++PL)
1056 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1057 return true;
1058
1059 return VisitObjCContainerDecl(PID);
1060}
1061
1062bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1063 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1064 return true;
1065
1066 // FIXME: This implements a workaround with @property declarations also being
1067 // installed in the DeclContext for the @interface. Eventually this code
1068 // should be removed.
1069 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1070 if (!CDecl || !CDecl->IsClassExtension())
1071 return false;
1072
1073 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1074 if (!ID)
1075 return false;
1076
1077 IdentifierInfo *PropertyId = PD->getIdentifier();
1078 ObjCPropertyDecl *prevDecl =
1079 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1080
1081 if (!prevDecl)
1082 return false;
1083
1084 // Visit synthesized methods since they will be skipped when visiting
1085 // the @interface.
1086 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1087 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1088 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1089 return true;
1090
1091 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1092 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1093 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1094 return true;
1095
1096 return false;
1097}
1098
Douglas Gregore9d95f12015-07-07 03:57:35 +00001099bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1100 if (!typeParamList)
1101 return false;
1102
1103 for (auto *typeParam : *typeParamList) {
1104 // Visit the type parameter.
1105 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1106 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001107 }
1108
1109 return false;
1110}
1111
Guy Benyei11169dd2012-12-18 14:30:41 +00001112bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1113 if (!D->isThisDeclarationADefinition()) {
1114 // Forward declaration is treated like a reference.
1115 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1116 }
1117
Douglas Gregore9d95f12015-07-07 03:57:35 +00001118 // Objective-C type parameters.
1119 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1120 return true;
1121
Guy Benyei11169dd2012-12-18 14:30:41 +00001122 // Issue callbacks for super class.
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128
Douglas Gregore9d95f12015-07-07 03:57:35 +00001129 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1130 if (Visit(SuperClassTInfo->getTypeLoc()))
1131 return true;
1132
Guy Benyei11169dd2012-12-18 14:30:41 +00001133 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1134 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1135 E = D->protocol_end(); I != E; ++I, ++PL)
1136 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1137 return true;
1138
1139 return VisitObjCContainerDecl(D);
1140}
1141
1142bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1143 return VisitObjCContainerDecl(D);
1144}
1145
1146bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1147 // 'ID' could be null when dealing with invalid code.
1148 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1149 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1150 return true;
1151
1152 return VisitObjCImplDecl(D);
1153}
1154
1155bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1156#if 0
1157 // Issue callbacks for super class.
1158 // FIXME: No source location information!
1159 if (D->getSuperClass() &&
1160 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1161 D->getSuperClassLoc(),
1162 TU)))
1163 return true;
1164#endif
1165
1166 return VisitObjCImplDecl(D);
1167}
1168
1169bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1170 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1171 if (PD->isIvarNameSpecified())
1172 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1173
1174 return false;
1175}
1176
1177bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1178 return VisitDeclContext(D);
1179}
1180
1181bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1188 D->getTargetNameLoc(), TU));
1189}
1190
1191bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1192 // Visit nested-name-specifier.
1193 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1194 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1195 return true;
1196 }
1197
1198 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1199 return true;
1200
1201 return VisitDeclarationNameInfo(D->getNameInfo());
1202}
1203
1204bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1205 // Visit nested-name-specifier.
1206 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1207 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1208 return true;
1209
1210 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1211 D->getIdentLocation(), TU));
1212}
1213
1214bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1215 // Visit nested-name-specifier.
1216 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1218 return true;
1219 }
1220
1221 return VisitDeclarationNameInfo(D->getNameInfo());
1222}
1223
1224bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1225 UnresolvedUsingTypenameDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
1230
1231 return false;
1232}
1233
1234bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1235 switch (Name.getName().getNameKind()) {
1236 case clang::DeclarationName::Identifier:
1237 case clang::DeclarationName::CXXLiteralOperatorName:
1238 case clang::DeclarationName::CXXOperatorName:
1239 case clang::DeclarationName::CXXUsingDirective:
1240 return false;
1241
1242 case clang::DeclarationName::CXXConstructorName:
1243 case clang::DeclarationName::CXXDestructorName:
1244 case clang::DeclarationName::CXXConversionFunctionName:
1245 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1246 return Visit(TSInfo->getTypeLoc());
1247 return false;
1248
1249 case clang::DeclarationName::ObjCZeroArgSelector:
1250 case clang::DeclarationName::ObjCOneArgSelector:
1251 case clang::DeclarationName::ObjCMultiArgSelector:
1252 // FIXME: Per-identifier location info?
1253 return false;
1254 }
1255
1256 llvm_unreachable("Invalid DeclarationName::Kind!");
1257}
1258
1259bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1260 SourceRange Range) {
1261 // FIXME: This whole routine is a hack to work around the lack of proper
1262 // source information in nested-name-specifiers (PR5791). Since we do have
1263 // a beginning source location, we can visit the first component of the
1264 // nested-name-specifier, if it's a single-token component.
1265 if (!NNS)
1266 return false;
1267
1268 // Get the first component in the nested-name-specifier.
1269 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1270 NNS = Prefix;
1271
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1275 TU));
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Range.getBegin(), TU));
1280
1281 case NestedNameSpecifier::TypeSpec: {
1282 // If the type has a form where we know that the beginning of the source
1283 // range matches up with a reference cursor. Visit the appropriate reference
1284 // cursor.
1285 const Type *T = NNS->getAsType();
1286 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1287 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1288 if (const TagType *Tag = dyn_cast<TagType>(T))
1289 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1290 if (const TemplateSpecializationType *TST
1291 = dyn_cast<TemplateSpecializationType>(T))
1292 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1293 break;
1294 }
1295
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 case NestedNameSpecifier::Global:
1298 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001299 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001300 break;
1301 }
1302
1303 return false;
1304}
1305
1306bool
1307CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1308 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1309 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1310 Qualifiers.push_back(Qualifier);
1311
1312 while (!Qualifiers.empty()) {
1313 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1314 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1315 switch (NNS->getKind()) {
1316 case NestedNameSpecifier::Namespace:
1317 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1318 Q.getLocalBeginLoc(),
1319 TU)))
1320 return true;
1321
1322 break;
1323
1324 case NestedNameSpecifier::NamespaceAlias:
1325 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1326 Q.getLocalBeginLoc(),
1327 TU)))
1328 return true;
1329
1330 break;
1331
1332 case NestedNameSpecifier::TypeSpec:
1333 case NestedNameSpecifier::TypeSpecWithTemplate:
1334 if (Visit(Q.getTypeLoc()))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::Global:
1340 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001341 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001342 break;
1343 }
1344 }
1345
1346 return false;
1347}
1348
1349bool CursorVisitor::VisitTemplateParameters(
1350 const TemplateParameterList *Params) {
1351 if (!Params)
1352 return false;
1353
1354 for (TemplateParameterList::const_iterator P = Params->begin(),
1355 PEnd = Params->end();
1356 P != PEnd; ++P) {
1357 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1364bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1365 switch (Name.getKind()) {
1366 case TemplateName::Template:
1367 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1368
1369 case TemplateName::OverloadedTemplate:
1370 // Visit the overloaded template set.
1371 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1372 return true;
1373
1374 return false;
1375
1376 case TemplateName::DependentTemplate:
1377 // FIXME: Visit nested-name-specifier.
1378 return false;
1379
1380 case TemplateName::QualifiedTemplate:
1381 // FIXME: Visit nested-name-specifier.
1382 return Visit(MakeCursorTemplateRef(
1383 Name.getAsQualifiedTemplateName()->getDecl(),
1384 Loc, TU));
1385
1386 case TemplateName::SubstTemplateTemplateParm:
1387 return Visit(MakeCursorTemplateRef(
1388 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1389 Loc, TU));
1390
1391 case TemplateName::SubstTemplateTemplateParmPack:
1392 return Visit(MakeCursorTemplateRef(
1393 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1394 Loc, TU));
1395 }
1396
1397 llvm_unreachable("Invalid TemplateName::Kind!");
1398}
1399
1400bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1401 switch (TAL.getArgument().getKind()) {
1402 case TemplateArgument::Null:
1403 case TemplateArgument::Integral:
1404 case TemplateArgument::Pack:
1405 return false;
1406
1407 case TemplateArgument::Type:
1408 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1409 return Visit(TSInfo->getTypeLoc());
1410 return false;
1411
1412 case TemplateArgument::Declaration:
1413 if (Expr *E = TAL.getSourceDeclExpression())
1414 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1415 return false;
1416
1417 case TemplateArgument::NullPtr:
1418 if (Expr *E = TAL.getSourceNullPtrExpression())
1419 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1420 return false;
1421
1422 case TemplateArgument::Expression:
1423 if (Expr *E = TAL.getSourceExpression())
1424 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1425 return false;
1426
1427 case TemplateArgument::Template:
1428 case TemplateArgument::TemplateExpansion:
1429 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1430 return true;
1431
1432 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1433 TAL.getTemplateNameLoc());
1434 }
1435
1436 llvm_unreachable("Invalid TemplateArgument::Kind!");
1437}
1438
1439bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1440 return VisitDeclContext(D);
1441}
1442
1443bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1444 return Visit(TL.getUnqualifiedLoc());
1445}
1446
1447bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1448 ASTContext &Context = AU->getASTContext();
1449
1450 // Some builtin types (such as Objective-C's "id", "sel", and
1451 // "Class") have associated declarations. Create cursors for those.
1452 QualType VisitType;
1453 switch (TL.getTypePtr()->getKind()) {
1454
1455 case BuiltinType::Void:
1456 case BuiltinType::NullPtr:
1457 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001458 case BuiltinType::OCLImage1d:
1459 case BuiltinType::OCLImage1dArray:
1460 case BuiltinType::OCLImage1dBuffer:
1461 case BuiltinType::OCLImage2d:
1462 case BuiltinType::OCLImage2dArray:
1463 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001464 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001465 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001466#define BUILTIN_TYPE(Id, SingletonId)
1467#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1468#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1469#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1470#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1471#include "clang/AST/BuiltinTypes.def"
1472 break;
1473
1474 case BuiltinType::ObjCId:
1475 VisitType = Context.getObjCIdType();
1476 break;
1477
1478 case BuiltinType::ObjCClass:
1479 VisitType = Context.getObjCClassType();
1480 break;
1481
1482 case BuiltinType::ObjCSel:
1483 VisitType = Context.getObjCSelType();
1484 break;
1485 }
1486
1487 if (!VisitType.isNull()) {
1488 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1489 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1490 TU));
1491 }
1492
1493 return false;
1494}
1495
1496bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1497 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1498}
1499
1500bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1501 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1502}
1503
1504bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1505 if (TL.isDefinition())
1506 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1507
1508 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1509}
1510
1511bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1512 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1513}
1514
1515bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1516 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1517 return true;
1518
1519 return false;
1520}
1521
1522bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1523 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1524 return true;
1525
Douglas Gregore9d95f12015-07-07 03:57:35 +00001526 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1527 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1528 return true;
1529 }
1530
Guy Benyei11169dd2012-12-18 14:30:41 +00001531 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1532 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1533 TU)))
1534 return true;
1535 }
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1541 return Visit(TL.getPointeeLoc());
1542}
1543
1544bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1545 return Visit(TL.getInnerLoc());
1546}
1547
1548bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1549 return Visit(TL.getPointeeLoc());
1550}
1551
1552bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1553 return Visit(TL.getPointeeLoc());
1554}
1555
1556bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1557 return Visit(TL.getPointeeLoc());
1558}
1559
1560bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1561 return Visit(TL.getPointeeLoc());
1562}
1563
1564bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1565 return Visit(TL.getPointeeLoc());
1566}
1567
1568bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1569 return Visit(TL.getModifiedLoc());
1570}
1571
1572bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1573 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001574 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001575 return true;
1576
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001577 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1578 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001579 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1580 return true;
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1586 if (Visit(TL.getElementLoc()))
1587 return true;
1588
1589 if (Expr *Size = TL.getSizeExpr())
1590 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1591
1592 return false;
1593}
1594
Reid Kleckner8a365022013-06-24 17:51:48 +00001595bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1596 return Visit(TL.getOriginalLoc());
1597}
1598
Reid Kleckner0503a872013-12-05 01:23:43 +00001599bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1600 return Visit(TL.getOriginalLoc());
1601}
1602
Guy Benyei11169dd2012-12-18 14:30:41 +00001603bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1604 TemplateSpecializationTypeLoc TL) {
1605 // Visit the template name.
1606 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1607 TL.getTemplateNameLoc()))
1608 return true;
1609
1610 // Visit the template arguments.
1611 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1612 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1613 return true;
1614
1615 return false;
1616}
1617
1618bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1619 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1620}
1621
1622bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1623 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1624 return Visit(TSInfo->getTypeLoc());
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1630 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1631 return Visit(TSInfo->getTypeLoc());
1632
1633 return false;
1634}
1635
1636bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1637 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1638 return true;
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1644 DependentTemplateSpecializationTypeLoc TL) {
1645 // Visit the nested-name-specifier, if there is one.
1646 if (TL.getQualifierLoc() &&
1647 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1648 return true;
1649
1650 // Visit the template arguments.
1651 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1652 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1653 return true;
1654
1655 return false;
1656}
1657
1658bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1659 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1660 return true;
1661
1662 return Visit(TL.getNamedTypeLoc());
1663}
1664
1665bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1666 return Visit(TL.getPatternLoc());
1667}
1668
1669bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1670 if (Expr *E = TL.getUnderlyingExpr())
1671 return Visit(MakeCXCursor(E, StmtParent, TU));
1672
1673 return false;
1674}
1675
1676bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1677 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1678}
1679
1680bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1681 return Visit(TL.getValueLoc());
1682}
1683
1684#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1685bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1686 return Visit##PARENT##Loc(TL); \
1687}
1688
1689DEFAULT_TYPELOC_IMPL(Complex, Type)
1690DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1691DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1692DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1693DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1694DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1695DEFAULT_TYPELOC_IMPL(Vector, Type)
1696DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1697DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1698DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1699DEFAULT_TYPELOC_IMPL(Record, TagType)
1700DEFAULT_TYPELOC_IMPL(Enum, TagType)
1701DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1702DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1703DEFAULT_TYPELOC_IMPL(Auto, Type)
1704
1705bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1706 // Visit the nested-name-specifier, if present.
1707 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1708 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1709 return true;
1710
1711 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001712 for (const auto &I : D->bases()) {
1713 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 return true;
1715 }
1716 }
1717
1718 return VisitTagDecl(D);
1719}
1720
1721bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001722 for (const auto *I : D->attrs())
1723 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 return true;
1725
1726 return false;
1727}
1728
1729//===----------------------------------------------------------------------===//
1730// Data-recursive visitor methods.
1731//===----------------------------------------------------------------------===//
1732
1733namespace {
1734#define DEF_JOB(NAME, DATA, KIND)\
1735class NAME : public VisitorJob {\
1736public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001737 NAME(const DATA *d, CXCursor parent) : \
1738 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001739 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001740 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001741};
1742
1743DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1744DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1745DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1746DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1747DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1748 ExplicitTemplateArgsVisitKind)
1749DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1750DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1751DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1752#undef DEF_JOB
1753
1754class DeclVisit : public VisitorJob {
1755public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001756 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001758 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001759 static bool classof(const VisitorJob *VJ) {
1760 return VJ->getKind() == DeclVisitKind;
1761 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001763 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001764};
1765class TypeLocVisit : public VisitorJob {
1766public:
1767 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1768 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1769 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1770
1771 static bool classof(const VisitorJob *VJ) {
1772 return VJ->getKind() == TypeLocVisitKind;
1773 }
1774
1775 TypeLoc get() const {
1776 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 }
1779};
1780
1781class LabelRefVisit : public VisitorJob {
1782public:
1783 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1784 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1785 labelLoc.getPtrEncoding()) {}
1786
1787 static bool classof(const VisitorJob *VJ) {
1788 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1789 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001790 const LabelDecl *get() const {
1791 return static_cast<const LabelDecl *>(data[0]);
1792 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 SourceLocation getLoc() const {
1794 return SourceLocation::getFromPtrEncoding(data[1]); }
1795};
1796
1797class NestedNameSpecifierLocVisit : public VisitorJob {
1798public:
1799 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1800 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1801 Qualifier.getNestedNameSpecifier(),
1802 Qualifier.getOpaqueData()) { }
1803
1804 static bool classof(const VisitorJob *VJ) {
1805 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1806 }
1807
1808 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 return NestedNameSpecifierLoc(
1810 const_cast<NestedNameSpecifier *>(
1811 static_cast<const NestedNameSpecifier *>(data[0])),
1812 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 }
1814};
1815
1816class DeclarationNameInfoVisit : public VisitorJob {
1817public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001818 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001819 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001820 static bool classof(const VisitorJob *VJ) {
1821 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1822 }
1823 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001824 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001825 switch (S->getStmtClass()) {
1826 default:
1827 llvm_unreachable("Unhandled Stmt");
1828 case clang::Stmt::MSDependentExistsStmtClass:
1829 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1830 case Stmt::CXXDependentScopeMemberExprClass:
1831 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1832 case Stmt::DependentScopeDeclRefExprClass:
1833 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001834 case Stmt::OMPCriticalDirectiveClass:
1835 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 }
1837 }
1838};
1839class MemberRefVisit : public VisitorJob {
1840public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001841 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001842 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1843 L.getPtrEncoding()) {}
1844 static bool classof(const VisitorJob *VJ) {
1845 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1846 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 const FieldDecl *get() const {
1848 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001849 }
1850 SourceLocation getLoc() const {
1851 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1852 }
1853};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001855 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001856 VisitorWorkList &WL;
1857 CXCursor Parent;
1858public:
1859 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1860 : WL(wl), Parent(parent) {}
1861
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1863 void VisitBlockExpr(const BlockExpr *B);
1864 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1865 void VisitCompoundStmt(const CompoundStmt *S);
1866 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1867 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1868 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1869 void VisitCXXNewExpr(const CXXNewExpr *E);
1870 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1871 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1872 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1873 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1874 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1875 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1876 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1877 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001878 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void VisitDeclRefExpr(const DeclRefExpr *D);
1880 void VisitDeclStmt(const DeclStmt *S);
1881 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1882 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1883 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1884 void VisitForStmt(const ForStmt *FS);
1885 void VisitGotoStmt(const GotoStmt *GS);
1886 void VisitIfStmt(const IfStmt *If);
1887 void VisitInitListExpr(const InitListExpr *IE);
1888 void VisitMemberExpr(const MemberExpr *M);
1889 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1890 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1891 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1892 void VisitOverloadExpr(const OverloadExpr *E);
1893 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1894 void VisitStmt(const Stmt *S);
1895 void VisitSwitchStmt(const SwitchStmt *S);
1896 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1898 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1899 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1900 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1901 void VisitVAArgExpr(const VAArgExpr *E);
1902 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1903 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1904 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1905 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001906 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001907 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001908 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001909 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001910 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001911 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001912 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001913 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001914 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001915 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001916 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001917 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001918 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001919 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001920 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001921 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001922 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001923 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001924 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001925 void
1926 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001927 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001928 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001929 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001930 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001931 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001932 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001933 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934
Guy Benyei11169dd2012-12-18 14:30:41 +00001935private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1938 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001939 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1940 void AddStmt(const Stmt *S);
1941 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001942 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001943 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001945};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001946} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001947
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 // 'S' should always be non-null, since it comes from the
1950 // statement we are visiting.
1951 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1952}
1953
1954void
1955EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1956 if (Qualifier)
1957 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1958}
1959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001961 if (S)
1962 WL.push_back(StmtVisit(S, Parent));
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 if (D)
1966 WL.push_back(DeclVisit(D, Parent, isFirst));
1967}
1968void EnqueueVisitor::
1969 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1970 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001972}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 if (D)
1975 WL.push_back(MemberRefVisit(D, L, Parent));
1976}
1977void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1978 if (TI)
1979 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1980 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001983 for (const Stmt *SubStmt : S->children()) {
1984 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 }
1986 if (size == WL.size())
1987 return;
1988 // Now reverse the entries we just added. This will match the DFS
1989 // ordering performed by the worklist.
1990 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1991 std::reverse(I, E);
1992}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001993namespace {
1994class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1995 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001996 /// \brief Process clauses with list of variables.
1997 template <typename T>
1998 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001999public:
2000 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2001#define OPENMP_CLAUSE(Name, Class) \
2002 void Visit##Class(const Class *C);
2003#include "clang/Basic/OpenMPKinds.def"
2004};
2005
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002006void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2007 Visitor->AddStmt(C->getCondition());
2008}
2009
Alexey Bataev3778b602014-07-17 07:32:53 +00002010void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2011 Visitor->AddStmt(C->getCondition());
2012}
2013
Alexey Bataev568a8332014-03-06 06:15:19 +00002014void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2015 Visitor->AddStmt(C->getNumThreads());
2016}
2017
Alexey Bataev62c87d22014-03-21 04:51:18 +00002018void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2019 Visitor->AddStmt(C->getSafelen());
2020}
2021
Alexey Bataev66b15b52015-08-21 11:14:16 +00002022void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2023 Visitor->AddStmt(C->getSimdlen());
2024}
2025
Alexander Musman8bd31e62014-05-27 15:12:19 +00002026void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2027 Visitor->AddStmt(C->getNumForLoops());
2028}
2029
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002030void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002031
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002032void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2033
Alexey Bataev56dafe82014-06-20 07:16:17 +00002034void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2035 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002036 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002037}
2038
Alexey Bataev10e775f2015-07-30 11:36:16 +00002039void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2040 Visitor->AddStmt(C->getNumForLoops());
2041}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002042
Alexey Bataev236070f2014-06-20 11:19:47 +00002043void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2044
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002045void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2046
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002047void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2048
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002049void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2050
Alexey Bataevdea47612014-07-23 07:46:59 +00002051void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2052
Alexey Bataev67a4f222014-07-23 10:25:33 +00002053void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2054
Alexey Bataev459dec02014-07-24 06:46:57 +00002055void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2056
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002057void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2058
Michael Wonge710d542015-08-07 16:16:36 +00002059void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2060 Visitor->AddStmt(C->getDevice());
2061}
2062
Alexey Bataev756c1962013-09-24 03:17:45 +00002063template<typename T>
2064void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002065 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002066 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002067 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002068}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002069
2070void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002071 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002072 for (const auto *E : C->private_copies()) {
2073 Visitor->AddStmt(E);
2074 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002075}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002076void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2077 const OMPFirstprivateClause *C) {
2078 VisitOMPClauseList(C);
2079}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002080void OMPClauseEnqueue::VisitOMPLastprivateClause(
2081 const OMPLastprivateClause *C) {
2082 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002083 for (auto *E : C->private_copies()) {
2084 Visitor->AddStmt(E);
2085 }
2086 for (auto *E : C->source_exprs()) {
2087 Visitor->AddStmt(E);
2088 }
2089 for (auto *E : C->destination_exprs()) {
2090 Visitor->AddStmt(E);
2091 }
2092 for (auto *E : C->assignment_ops()) {
2093 Visitor->AddStmt(E);
2094 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002095}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002096void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002097 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002098}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002099void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2100 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002101 for (auto *E : C->lhs_exprs()) {
2102 Visitor->AddStmt(E);
2103 }
2104 for (auto *E : C->rhs_exprs()) {
2105 Visitor->AddStmt(E);
2106 }
2107 for (auto *E : C->reduction_ops()) {
2108 Visitor->AddStmt(E);
2109 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002110}
Alexander Musman8dba6642014-04-22 13:09:42 +00002111void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2112 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002113 for (const auto *E : C->privates()) {
2114 Visitor->AddStmt(E);
2115 }
Alexander Musman3276a272015-03-21 10:12:56 +00002116 for (const auto *E : C->inits()) {
2117 Visitor->AddStmt(E);
2118 }
2119 for (const auto *E : C->updates()) {
2120 Visitor->AddStmt(E);
2121 }
2122 for (const auto *E : C->finals()) {
2123 Visitor->AddStmt(E);
2124 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002125 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002126 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002127}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002128void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2129 VisitOMPClauseList(C);
2130 Visitor->AddStmt(C->getAlignment());
2131}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002132void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2133 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002134 for (auto *E : C->source_exprs()) {
2135 Visitor->AddStmt(E);
2136 }
2137 for (auto *E : C->destination_exprs()) {
2138 Visitor->AddStmt(E);
2139 }
2140 for (auto *E : C->assignment_ops()) {
2141 Visitor->AddStmt(E);
2142 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002143}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002144void
2145OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2146 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002147 for (auto *E : C->source_exprs()) {
2148 Visitor->AddStmt(E);
2149 }
2150 for (auto *E : C->destination_exprs()) {
2151 Visitor->AddStmt(E);
2152 }
2153 for (auto *E : C->assignment_ops()) {
2154 Visitor->AddStmt(E);
2155 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002156}
Alexey Bataev6125da92014-07-21 11:26:11 +00002157void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2158 VisitOMPClauseList(C);
2159}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002160void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2161 VisitOMPClauseList(C);
2162}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002163}
Alexey Bataev756c1962013-09-24 03:17:45 +00002164
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002165void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2166 unsigned size = WL.size();
2167 OMPClauseEnqueue Visitor(this);
2168 Visitor.Visit(S);
2169 if (size == WL.size())
2170 return;
2171 // Now reverse the entries we just added. This will match the DFS
2172 // ordering performed by the worklist.
2173 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2174 std::reverse(I, E);
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddDecl(B->getBlockDecl());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(E);
2184 AddTypeLoc(E->getTypeSourceInfo());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002187 for (auto &I : llvm::reverse(S->body()))
2188 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002189}
2190void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(S->getSubStmt());
2193 AddDeclarationNameInfo(S);
2194 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2195 AddNestedNameSpecifierLoc(QualifierLoc);
2196}
2197
2198void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2201 AddDeclarationNameInfo(E);
2202 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2203 AddNestedNameSpecifierLoc(QualifierLoc);
2204 if (!E->isImplicitAccess())
2205 AddStmt(E->getBase());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 // Enqueue the initializer , if any.
2209 AddStmt(E->getInitializer());
2210 // Enqueue the array size, if any.
2211 AddStmt(E->getArraySize());
2212 // Enqueue the allocated type.
2213 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2214 // Enqueue the placement arguments.
2215 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2216 AddStmt(E->getPlacementArg(I-1));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2220 AddStmt(CE->getArg(I-1));
2221 AddStmt(CE->getCallee());
2222 AddStmt(CE->getArg(0));
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2225 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // Visit the name of the type being destroyed.
2227 AddTypeLoc(E->getDestroyedTypeInfo());
2228 // Visit the scope type that looks disturbingly like the nested-name-specifier
2229 // but isn't.
2230 AddTypeLoc(E->getScopeTypeInfo());
2231 // Visit the nested-name-specifier.
2232 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2233 AddNestedNameSpecifierLoc(QualifierLoc);
2234 // Visit base expression.
2235 AddStmt(E->getBase());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2238 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddTypeLoc(E->getTypeSourceInfo());
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2242 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 EnqueueChildren(E);
2244 AddTypeLoc(E->getTypeSourceInfo());
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(E);
2248 if (E->isTypeOperand())
2249 AddTypeLoc(E->getTypeOperandSourceInfo());
2250}
2251
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2253 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 AddTypeLoc(E->getTypeSourceInfo());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueChildren(E);
2259 if (E->isTypeOperand())
2260 AddTypeLoc(E->getTypeOperandSourceInfo());
2261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 EnqueueChildren(S);
2265 AddDecl(S->getExceptionDecl());
2266}
2267
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002268void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002269 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002270 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002271 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 if (DR->hasExplicitTemplateArgs()) {
2276 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2277 }
2278 WL.push_back(DeclRefExprParts(DR, Parent));
2279}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2281 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2283 AddDeclarationNameInfo(E);
2284 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 unsigned size = WL.size();
2288 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002289 for (const auto *D : S->decls()) {
2290 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 isFirst = false;
2292 }
2293 if (size == WL.size())
2294 return;
2295 // Now reverse the entries we just added. This will match the DFS
2296 // ordering performed by the worklist.
2297 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2298 std::reverse(I, E);
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 D = E->designators_rbegin(), DEnd = E->designators_rend();
2304 D != DEnd; ++D) {
2305 if (D->isFieldDesignator()) {
2306 if (FieldDecl *Field = D->getField())
2307 AddMemberRef(Field, D->getFieldLoc());
2308 continue;
2309 }
2310 if (D->isArrayDesignator()) {
2311 AddStmt(E->getArrayIndex(*D));
2312 continue;
2313 }
2314 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2315 AddStmt(E->getArrayRangeEnd(*D));
2316 AddStmt(E->getArrayRangeStart(*D));
2317 }
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 EnqueueChildren(E);
2321 AddTypeLoc(E->getTypeInfoAsWritten());
2322}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 AddStmt(FS->getBody());
2325 AddStmt(FS->getInc());
2326 AddStmt(FS->getCond());
2327 AddDecl(FS->getConditionVariable());
2328 AddStmt(FS->getInit());
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 AddStmt(If->getElse());
2335 AddStmt(If->getThen());
2336 AddStmt(If->getCond());
2337 AddDecl(If->getConditionVariable());
2338}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 // We care about the syntactic form of the initializer list, only.
2341 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2342 IE = Syntactic;
2343 EnqueueChildren(IE);
2344}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 WL.push_back(MemberExprParts(M, Parent));
2347
2348 // If the base of the member access expression is an implicit 'this', don't
2349 // visit it.
2350 // FIXME: If we ever want to show these implicit accesses, this will be
2351 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002352 if (M->isImplicitAccess())
2353 return;
2354
2355 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2356 // real field that that we are interested in.
2357 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2358 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2359 if (FD->isAnonymousStructOrUnion()) {
2360 AddStmt(SubME->getBase());
2361 return;
2362 }
2363 }
2364 }
2365
2366 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddTypeLoc(E->getEncodedTypeSourceInfo());
2370}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 EnqueueChildren(M);
2373 AddTypeLoc(M->getClassReceiverTypeInfo());
2374}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 // Visit the components of the offsetof expression.
2377 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2378 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2379 const OffsetOfNode &Node = E->getComponent(I-1);
2380 switch (Node.getKind()) {
2381 case OffsetOfNode::Array:
2382 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2383 break;
2384 case OffsetOfNode::Field:
2385 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2386 break;
2387 case OffsetOfNode::Identifier:
2388 case OffsetOfNode::Base:
2389 continue;
2390 }
2391 }
2392 // Visit the type into which we're computing the offset.
2393 AddTypeLoc(E->getTypeSourceInfo());
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2397 WL.push_back(OverloadExprParts(E, Parent));
2398}
2399void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueChildren(E);
2402 if (E->isArgumentType())
2403 AddTypeLoc(E->getArgumentTypeInfo());
2404}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002405void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 EnqueueChildren(S);
2407}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 AddStmt(S->getBody());
2410 AddStmt(S->getCond());
2411 AddDecl(S->getConditionVariable());
2412}
2413
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 AddStmt(W->getBody());
2416 AddStmt(W->getCond());
2417 AddDecl(W->getConditionVariable());
2418}
2419
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 for (unsigned I = E->getNumArgs(); I > 0; --I)
2422 AddTypeLoc(E->getArg(I-1));
2423}
2424
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 AddTypeLoc(E->getQueriedTypeSourceInfo());
2427}
2428
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 EnqueueChildren(E);
2431}
2432
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 VisitOverloadExpr(U);
2435 if (!U->isImplicitAccess())
2436 AddStmt(U->getBase());
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 AddStmt(E->getSubExpr());
2440 AddTypeLoc(E->getWrittenTypeInfo());
2441}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 WL.push_back(SizeOfPackExprParts(E, Parent));
2444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 // If the opaque value has a source expression, just transparently
2447 // visit that. This is useful for (e.g.) pseudo-object expressions.
2448 if (Expr *SourceExpr = E->getSourceExpr())
2449 return Visit(SourceExpr);
2450}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 AddStmt(E->getBody());
2453 WL.push_back(LambdaExprParts(E, Parent));
2454}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 // Treat the expression like its syntactic form.
2457 Visit(E->getSyntacticForm());
2458}
2459
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002460void EnqueueVisitor::VisitOMPExecutableDirective(
2461 const OMPExecutableDirective *D) {
2462 EnqueueChildren(D);
2463 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2464 E = D->clauses().end();
2465 I != E; ++I)
2466 EnqueueChildren(*I);
2467}
2468
Alexander Musman3aaab662014-08-19 11:27:13 +00002469void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2470 VisitOMPExecutableDirective(D);
2471}
2472
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002473void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2474 VisitOMPExecutableDirective(D);
2475}
2476
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002477void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002478 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002479}
2480
Alexey Bataevf29276e2014-06-18 04:14:57 +00002481void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002482 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002483}
2484
Alexander Musmanf82886e2014-09-18 05:12:34 +00002485void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2486 VisitOMPLoopDirective(D);
2487}
2488
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002489void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2490 VisitOMPExecutableDirective(D);
2491}
2492
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002493void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2494 VisitOMPExecutableDirective(D);
2495}
2496
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002497void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Alexander Musman80c22892014-07-17 08:54:58 +00002501void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503}
2504
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002505void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2506 VisitOMPExecutableDirective(D);
2507 AddDeclarationNameInfo(D);
2508}
2509
Alexey Bataev4acb8592014-07-07 13:01:15 +00002510void
2511EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002512 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002513}
2514
Alexander Musmane4e893b2014-09-23 09:33:00 +00002515void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2516 const OMPParallelForSimdDirective *D) {
2517 VisitOMPLoopDirective(D);
2518}
2519
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002520void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2521 const OMPParallelSectionsDirective *D) {
2522 VisitOMPExecutableDirective(D);
2523}
2524
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002525void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2526 VisitOMPExecutableDirective(D);
2527}
2528
Alexey Bataev68446b72014-07-18 07:47:19 +00002529void
2530EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002534void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataev2df347a2014-07-18 10:17:07 +00002538void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002542void EnqueueVisitor::VisitOMPTaskgroupDirective(
2543 const OMPTaskgroupDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataev6125da92014-07-21 11:26:11 +00002547void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2548 VisitOMPExecutableDirective(D);
2549}
2550
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002551void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev0162e452014-07-22 10:10:35 +00002555void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002559void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Michael Wong65f367f2015-07-21 13:44:28 +00002563void EnqueueVisitor::VisitOMPTargetDataDirective(const
2564 OMPTargetDataDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev13314bf2014-10-09 04:18:56 +00002568void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002572void EnqueueVisitor::VisitOMPCancellationPointDirective(
2573 const OMPCancellationPointDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexey Bataev80909872015-07-02 11:25:17 +00002577void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579}
2580
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002581void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2583}
2584
2585bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2586 if (RegionOfInterest.isValid()) {
2587 SourceRange Range = getRawCursorExtent(C);
2588 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2589 return false;
2590 }
2591 return true;
2592}
2593
2594bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2595 while (!WL.empty()) {
2596 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002597 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598
2599 // Set the Parent field, then back to its old value once we're done.
2600 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2601
2602 switch (LI.getKind()) {
2603 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 if (!D)
2606 continue;
2607
2608 // For now, perform default visitation for Decls.
2609 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2610 cast<DeclVisit>(&LI)->isFirst())))
2611 return true;
2612
2613 continue;
2614 }
2615 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2616 const ASTTemplateArgumentListInfo *ArgList =
2617 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2618 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2619 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2620 Arg != ArgEnd; ++Arg) {
2621 if (VisitTemplateArgumentLoc(*Arg))
2622 return true;
2623 }
2624 continue;
2625 }
2626 case VisitorJob::TypeLocVisitKind: {
2627 // Perform default visitation for TypeLocs.
2628 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2629 return true;
2630 continue;
2631 }
2632 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 if (LabelStmt *stmt = LS->getStmt()) {
2635 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2636 TU))) {
2637 return true;
2638 }
2639 }
2640 continue;
2641 }
2642
2643 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2644 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2645 if (VisitNestedNameSpecifierLoc(V->get()))
2646 return true;
2647 continue;
2648 }
2649
2650 case VisitorJob::DeclarationNameInfoVisitKind: {
2651 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2652 ->get()))
2653 return true;
2654 continue;
2655 }
2656 case VisitorJob::MemberRefVisitKind: {
2657 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2658 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2659 return true;
2660 continue;
2661 }
2662 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002663 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 if (!S)
2665 continue;
2666
2667 // Update the current cursor.
2668 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2669 if (!IsInRegionOfInterest(Cursor))
2670 continue;
2671 switch (Visitor(Cursor, Parent, ClientData)) {
2672 case CXChildVisit_Break: return true;
2673 case CXChildVisit_Continue: break;
2674 case CXChildVisit_Recurse:
2675 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002676 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 EnqueueWorkList(WL, S);
2678 break;
2679 }
2680 continue;
2681 }
2682 case VisitorJob::MemberExprPartsKind: {
2683 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002684 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002685
2686 // Visit the nested-name-specifier
2687 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2688 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2689 return true;
2690
2691 // Visit the declaration name.
2692 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2693 return true;
2694
2695 // Visit the explicitly-specified template arguments, if any.
2696 if (M->hasExplicitTemplateArgs()) {
2697 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2698 *ArgEnd = Arg + M->getNumTemplateArgs();
2699 Arg != ArgEnd; ++Arg) {
2700 if (VisitTemplateArgumentLoc(*Arg))
2701 return true;
2702 }
2703 }
2704 continue;
2705 }
2706 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002707 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 // Visit nested-name-specifier, if present.
2709 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2710 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2711 return true;
2712 // Visit declaration name.
2713 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2714 return true;
2715 continue;
2716 }
2717 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 // Visit the nested-name-specifier.
2720 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2721 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2722 return true;
2723 // Visit the declaration name.
2724 if (VisitDeclarationNameInfo(O->getNameInfo()))
2725 return true;
2726 // Visit the overloaded declaration reference.
2727 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2728 return true;
2729 continue;
2730 }
2731 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 NamedDecl *Pack = E->getPack();
2734 if (isa<TemplateTypeParmDecl>(Pack)) {
2735 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2736 E->getPackLoc(), TU)))
2737 return true;
2738
2739 continue;
2740 }
2741
2742 if (isa<TemplateTemplateParmDecl>(Pack)) {
2743 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2744 E->getPackLoc(), TU)))
2745 return true;
2746
2747 continue;
2748 }
2749
2750 // Non-type template parameter packs and function parameter packs are
2751 // treated like DeclRefExpr cursors.
2752 continue;
2753 }
2754
2755 case VisitorJob::LambdaExprPartsKind: {
2756 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002757 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2759 CEnd = E->explicit_capture_end();
2760 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002761 // FIXME: Lambda init-captures.
2762 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002763 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002764
Guy Benyei11169dd2012-12-18 14:30:41 +00002765 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2766 C->getLocation(),
2767 TU)))
2768 return true;
2769 }
2770
2771 // Visit parameters and return type, if present.
2772 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2773 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2774 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2775 // Visit the whole type.
2776 if (Visit(TL))
2777 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002778 } else if (FunctionProtoTypeLoc Proto =
2779 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002780 if (E->hasExplicitParameters()) {
2781 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002782 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2783 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 return true;
2785 } else {
2786 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002787 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 return true;
2789 }
2790 }
2791 }
2792 break;
2793 }
2794
2795 case VisitorJob::PostChildrenVisitKind:
2796 if (PostChildrenVisitor(Parent, ClientData))
2797 return true;
2798 break;
2799 }
2800 }
2801 return false;
2802}
2803
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002804bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002805 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 if (!WorkListFreeList.empty()) {
2807 WL = WorkListFreeList.back();
2808 WL->clear();
2809 WorkListFreeList.pop_back();
2810 }
2811 else {
2812 WL = new VisitorWorkList();
2813 WorkListCache.push_back(WL);
2814 }
2815 EnqueueWorkList(*WL, S);
2816 bool result = RunVisitorWorkList(*WL);
2817 WorkListFreeList.push_back(WL);
2818 return result;
2819}
2820
2821namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002822typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002823RefNamePieces
2824buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2825 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2826 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2828 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2829 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2830
2831 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2832
2833 RefNamePieces Pieces;
2834
2835 if (WantQualifier && QLoc.isValid())
2836 Pieces.push_back(QLoc);
2837
2838 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2839 Pieces.push_back(NI.getLoc());
2840
2841 if (WantTemplateArgs && TemplateArgs)
2842 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2843 TemplateArgs->RAngleLoc));
2844
2845 if (Kind == DeclarationName::CXXOperatorName) {
2846 Pieces.push_back(SourceLocation::getFromRawEncoding(
2847 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2848 Pieces.push_back(SourceLocation::getFromRawEncoding(
2849 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2850 }
2851
2852 if (WantSinglePiece) {
2853 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2854 Pieces.clear();
2855 Pieces.push_back(R);
2856 }
2857
2858 return Pieces;
2859}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002860}
Guy Benyei11169dd2012-12-18 14:30:41 +00002861
2862//===----------------------------------------------------------------------===//
2863// Misc. API hooks.
2864//===----------------------------------------------------------------------===//
2865
Chad Rosier05c71aa2013-03-27 18:28:23 +00002866static void fatal_error_handler(void *user_data, const std::string& reason,
2867 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002868 // Write the result out to stderr avoiding errs() because raw_ostreams can
2869 // call report_fatal_error.
2870 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2871 ::abort();
2872}
2873
Chandler Carruth66660742014-06-27 16:37:27 +00002874namespace {
2875struct RegisterFatalErrorHandler {
2876 RegisterFatalErrorHandler() {
2877 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2878 }
2879};
2880}
2881
2882static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2883
Guy Benyei11169dd2012-12-18 14:30:41 +00002884extern "C" {
2885CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2886 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 // We use crash recovery to make some of our APIs more reliable, implicitly
2888 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002889 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2890 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002891
Chandler Carruth66660742014-06-27 16:37:27 +00002892 // Look through the managed static to trigger construction of the managed
2893 // static which registers our fatal error handler. This ensures it is only
2894 // registered once.
2895 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002896
Adrian Prantlbc068582015-07-08 01:00:30 +00002897 // Initialize targets for clang module support.
2898 llvm::InitializeAllTargets();
2899 llvm::InitializeAllTargetMCs();
2900 llvm::InitializeAllAsmPrinters();
2901 llvm::InitializeAllAsmParsers();
2902
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002903 CIndexer *CIdxr = new CIndexer();
2904
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (excludeDeclarationsFromPCH)
2906 CIdxr->setOnlyLocalDecls();
2907 if (displayDiagnostics)
2908 CIdxr->setDisplayDiagnostics();
2909
2910 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2911 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2912 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2913 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2914 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2915 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2916
2917 return CIdxr;
2918}
2919
2920void clang_disposeIndex(CXIndex CIdx) {
2921 if (CIdx)
2922 delete static_cast<CIndexer *>(CIdx);
2923}
2924
2925void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2926 if (CIdx)
2927 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2928}
2929
2930unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2931 if (CIdx)
2932 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2933 return 0;
2934}
2935
2936void clang_toggleCrashRecovery(unsigned isEnabled) {
2937 if (isEnabled)
2938 llvm::CrashRecoveryContext::Enable();
2939 else
2940 llvm::CrashRecoveryContext::Disable();
2941}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002942
Guy Benyei11169dd2012-12-18 14:30:41 +00002943CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2944 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002945 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002946 enum CXErrorCode Result =
2947 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002948 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002949 assert((TU && Result == CXError_Success) ||
2950 (!TU && Result != CXError_Success));
2951 return TU;
2952}
2953
2954enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2955 const char *ast_filename,
2956 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002957 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002958 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002959
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960 if (!CIdx || !ast_filename || !out_TU)
2961 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002963 LOG_FUNC_SECTION {
2964 *Log << ast_filename;
2965 }
2966
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2968 FileSystemOptions FileSystemOpts;
2969
Justin Bognerd512c1e2014-10-15 00:33:06 +00002970 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2971 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002972 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002973 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
2974 FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002975 /*CaptureDiagnostics=*/true,
2976 /*AllowPCHWithCompilerErrors=*/true,
2977 /*UserFilesAreVolatile=*/true);
2978 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002980}
2981
2982unsigned clang_defaultEditingTranslationUnitOptions() {
2983 return CXTranslationUnit_PrecompiledPreamble |
2984 CXTranslationUnit_CacheCompletionResults;
2985}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002986
Guy Benyei11169dd2012-12-18 14:30:41 +00002987CXTranslationUnit
2988clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2989 const char *source_filename,
2990 int num_command_line_args,
2991 const char * const *command_line_args,
2992 unsigned num_unsaved_files,
2993 struct CXUnsavedFile *unsaved_files) {
2994 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2995 return clang_parseTranslationUnit(CIdx, source_filename,
2996 command_line_args, num_command_line_args,
2997 unsaved_files, num_unsaved_files,
2998 Options);
2999}
3000
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003001static CXErrorCode
3002clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3003 const char *const *command_line_args,
3004 int num_command_line_args,
3005 ArrayRef<CXUnsavedFile> unsaved_files,
3006 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003007 // Set up the initial return values.
3008 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003009 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003010
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003012 if (!CIdx || !out_TU)
3013 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003014
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3016
3017 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3018 setThreadBackgroundPriority();
3019
3020 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3021 // FIXME: Add a flag for modules.
3022 TranslationUnitKind TUKind
3023 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003024 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003025 = options & CXTranslationUnit_CacheCompletionResults;
3026 bool IncludeBriefCommentsInCodeCompletion
3027 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3028 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3029 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3030
3031 // Configure the diagnostics.
3032 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003033 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003034
3035 // Recover resources if we crash before exiting this function.
3036 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3037 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003038 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003039
Ahmed Charlesb8984322014-03-07 20:03:18 +00003040 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3041 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 // Recover resources if we crash before exiting this function.
3044 llvm::CrashRecoveryContextCleanupRegistrar<
3045 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3046
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003047 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003048 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003049 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003050 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 }
3052
Ahmed Charlesb8984322014-03-07 20:03:18 +00003053 std::unique_ptr<std::vector<const char *>> Args(
3054 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003055
3056 // Recover resources if we crash before exiting this method.
3057 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3058 ArgsCleanup(Args.get());
3059
3060 // Since the Clang C library is primarily used by batch tools dealing with
3061 // (often very broken) source code, where spell-checking can have a
3062 // significant negative impact on performance (particularly when
3063 // precompiled headers are involved), we disable it by default.
3064 // Only do this if we haven't found a spell-checking-related argument.
3065 bool FoundSpellCheckingArgument = false;
3066 for (int I = 0; I != num_command_line_args; ++I) {
3067 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3068 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3069 FoundSpellCheckingArgument = true;
3070 break;
3071 }
3072 }
3073 if (!FoundSpellCheckingArgument)
3074 Args->push_back("-fno-spell-checking");
3075
3076 Args->insert(Args->end(), command_line_args,
3077 command_line_args + num_command_line_args);
3078
3079 // The 'source_filename' argument is optional. If the caller does not
3080 // specify it then it is assumed that the source file is specified
3081 // in the actual argument list.
3082 // Put the source file after command_line_args otherwise if '-x' flag is
3083 // present it will be unused.
3084 if (source_filename)
3085 Args->push_back(source_filename);
3086
3087 // Do we need the detailed preprocessing record?
3088 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3089 Args->push_back("-Xclang");
3090 Args->push_back("-detailed-preprocessing-record");
3091 }
3092
3093 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003094 std::unique_ptr<ASTUnit> ErrUnit;
3095 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003096 Args->data(), Args->data() + Args->size(),
3097 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003098 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3099 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3100 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3101 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3102 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3103 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003105 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003106 if (!Unit && !ErrUnit)
3107 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003108
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 if (NumErrors != Diags->getClient()->getNumErrors()) {
3110 // Make sure to check that 'Unit' is non-NULL.
3111 if (CXXIdx->getDisplayDiagnostics())
3112 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3113 }
3114
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003115 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3116 return CXError_ASTReadError;
3117
3118 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3119 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121
3122CXTranslationUnit
3123clang_parseTranslationUnit(CXIndex CIdx,
3124 const char *source_filename,
3125 const char *const *command_line_args,
3126 int num_command_line_args,
3127 struct CXUnsavedFile *unsaved_files,
3128 unsigned num_unsaved_files,
3129 unsigned options) {
3130 CXTranslationUnit TU;
3131 enum CXErrorCode Result = clang_parseTranslationUnit2(
3132 CIdx, source_filename, command_line_args, num_command_line_args,
3133 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003134 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003135 assert((TU && Result == CXError_Success) ||
3136 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003137 return TU;
3138}
3139
3140enum CXErrorCode clang_parseTranslationUnit2(
3141 CXIndex CIdx,
3142 const char *source_filename,
3143 const char *const *command_line_args,
3144 int num_command_line_args,
3145 struct CXUnsavedFile *unsaved_files,
3146 unsigned num_unsaved_files,
3147 unsigned options,
3148 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003149 LOG_FUNC_SECTION {
3150 *Log << source_filename << ": ";
3151 for (int i = 0; i != num_command_line_args; ++i)
3152 *Log << command_line_args[i] << " ";
3153 }
3154
Alp Toker9d85b182014-07-07 01:23:14 +00003155 if (num_unsaved_files && !unsaved_files)
3156 return CXError_InvalidArguments;
3157
Alp Toker5c532982014-07-07 22:42:03 +00003158 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003159 auto ParseTranslationUnitImpl = [=, &result] {
3160 result = clang_parseTranslationUnit_Impl(
3161 CIdx, source_filename, command_line_args, num_command_line_args,
3162 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3163 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 llvm::CrashRecoveryContext CRC;
3165
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003166 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3168 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3169 fprintf(stderr, " 'command_line_args' : [");
3170 for (int i = 0; i != num_command_line_args; ++i) {
3171 if (i)
3172 fprintf(stderr, ", ");
3173 fprintf(stderr, "'%s'", command_line_args[i]);
3174 }
3175 fprintf(stderr, "],\n");
3176 fprintf(stderr, " 'unsaved_files' : [");
3177 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3178 if (i)
3179 fprintf(stderr, ", ");
3180 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3181 unsaved_files[i].Length);
3182 }
3183 fprintf(stderr, "],\n");
3184 fprintf(stderr, " 'options' : %d,\n", options);
3185 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003186
3187 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003189 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003190 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 }
Alp Toker5c532982014-07-07 22:42:03 +00003192
3193 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003194}
3195
3196unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3197 return CXSaveTranslationUnit_None;
3198}
3199
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003200static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3201 const char *FileName,
3202 unsigned options) {
3203 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3205 setThreadBackgroundPriority();
3206
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003207 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3208 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003209}
3210
3211int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3212 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003213 LOG_FUNC_SECTION {
3214 *Log << TU << ' ' << FileName;
3215 }
3216
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003217 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003218 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003220 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003221
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003222 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3224 if (!CXXUnit->hasSema())
3225 return CXSaveError_InvalidTU;
3226
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003227 CXSaveError result;
3228 auto SaveTranslationUnitImpl = [=, &result]() {
3229 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3230 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003231
3232 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3233 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003234 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003235
3236 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3237 PrintLibclangResourceUsage(TU);
3238
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003239 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 }
3241
3242 // We have an AST that has invalid nodes due to compiler errors.
3243 // Use a crash recovery thread for protection.
3244
3245 llvm::CrashRecoveryContext CRC;
3246
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003247 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3249 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3250 fprintf(stderr, " 'options' : %d,\n", options);
3251 fprintf(stderr, "}\n");
3252
3253 return CXSaveError_Unknown;
3254
3255 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3256 PrintLibclangResourceUsage(TU);
3257 }
3258
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003259 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003260}
3261
3262void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3263 if (CTUnit) {
3264 // If the translation unit has been marked as unsafe to free, just discard
3265 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003266 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3267 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 return;
3269
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003270 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003271 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3273 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003274 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 delete CTUnit;
3276 }
3277}
3278
3279unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3280 return CXReparse_None;
3281}
3282
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003283static CXErrorCode
3284clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3285 ArrayRef<CXUnsavedFile> unsaved_files,
3286 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003287 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003288 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003289 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003290 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003291 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 // Reset the associated diagnostics.
3294 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003295 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003296
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003297 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3299 setThreadBackgroundPriority();
3300
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003301 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003303
3304 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3305 new std::vector<ASTUnit::RemappedFile>());
3306
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 // Recover resources if we crash before exiting this function.
3308 llvm::CrashRecoveryContextCleanupRegistrar<
3309 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003310
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003311 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003312 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003313 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003314 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003316
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003317 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3318 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003319 return CXError_Success;
3320 if (isASTReadError(CXXUnit))
3321 return CXError_ASTReadError;
3322 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003323}
3324
3325int clang_reparseTranslationUnit(CXTranslationUnit TU,
3326 unsigned num_unsaved_files,
3327 struct CXUnsavedFile *unsaved_files,
3328 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003329 LOG_FUNC_SECTION {
3330 *Log << TU;
3331 }
3332
Alp Toker9d85b182014-07-07 01:23:14 +00003333 if (num_unsaved_files && !unsaved_files)
3334 return CXError_InvalidArguments;
3335
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003336 CXErrorCode result;
3337 auto ReparseTranslationUnitImpl = [=, &result]() {
3338 result = clang_reparseTranslationUnit_Impl(
3339 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3340 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
3342 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003343 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003344 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 }
3346
3347 llvm::CrashRecoveryContext CRC;
3348
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003349 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003351 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003352 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3354 PrintLibclangResourceUsage(TU);
3355
Alp Toker5c532982014-07-07 22:42:03 +00003356 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003357}
3358
3359
3360CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003361 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003362 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003363 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003364 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003365
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003366 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368}
3369
3370CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003371 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003372 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003373 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003374 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003375
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003376 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3378}
3379
3380} // end: extern "C"
3381
3382//===----------------------------------------------------------------------===//
3383// CXFile Operations.
3384//===----------------------------------------------------------------------===//
3385
3386extern "C" {
3387CXString clang_getFileName(CXFile SFile) {
3388 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003389 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003390
3391 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003392 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393}
3394
3395time_t clang_getFileTime(CXFile SFile) {
3396 if (!SFile)
3397 return 0;
3398
3399 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3400 return FEnt->getModificationTime();
3401}
3402
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003403CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003405 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003406 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003407 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003408
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003409 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003410
3411 FileManager &FMgr = CXXUnit->getFileManager();
3412 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3413}
3414
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003415unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3416 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003417 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003418 LOG_BAD_TU(TU);
3419 return 0;
3420 }
3421
3422 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 return 0;
3424
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003425 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 FileEntry *FEnt = static_cast<FileEntry *>(file);
3427 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3428 .isFileMultipleIncludeGuarded(FEnt);
3429}
3430
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003431int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3432 if (!file || !outID)
3433 return 1;
3434
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003435 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003436 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3437 outID->data[0] = ID.getDevice();
3438 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003439 outID->data[2] = FEnt->getModificationTime();
3440 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003441}
3442
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003443int clang_File_isEqual(CXFile file1, CXFile file2) {
3444 if (file1 == file2)
3445 return true;
3446
3447 if (!file1 || !file2)
3448 return false;
3449
3450 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3451 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3452 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3453}
3454
Guy Benyei11169dd2012-12-18 14:30:41 +00003455} // end: extern "C"
3456
3457//===----------------------------------------------------------------------===//
3458// CXCursor Operations.
3459//===----------------------------------------------------------------------===//
3460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003461static const Decl *getDeclFromExpr(const Stmt *E) {
3462 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 return getDeclFromExpr(CE->getSubExpr());
3464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003469 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 if (PRE->isExplicitProperty())
3473 return PRE->getExplicitProperty();
3474 // It could be messaging both getter and setter as in:
3475 // ++myobj.myprop;
3476 // in which case prefer to associate the setter since it is less obvious
3477 // from inspecting the source that the setter is going to get called.
3478 if (PRE->isMessagingSetter())
3479 return PRE->getImplicitPropertySetter();
3480 return PRE->getImplicitPropertyGetter();
3481 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 if (Expr *Src = OVE->getSourceExpr())
3486 return getDeclFromExpr(Src);
3487
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003488 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 if (!CE->isElidable())
3492 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003493 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 return OME->getMethodDecl();
3495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3500 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3503 isa<ParmVarDecl>(SizeOfPack->getPack()))
3504 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003505
3506 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003507}
3508
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003509static SourceLocation getLocationFromExpr(const Expr *E) {
3510 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 return getLocationFromExpr(CE->getSubExpr());
3512
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003513 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003515 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003517 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003521 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003523 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return PropRef->getLocation();
3525
3526 return E->getLocStart();
3527}
3528
3529extern "C" {
3530
3531unsigned clang_visitChildren(CXCursor parent,
3532 CXCursorVisitor visitor,
3533 CXClientData client_data) {
3534 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3535 /*VisitPreprocessorLast=*/false);
3536 return CursorVis.VisitChildren(parent);
3537}
3538
3539#ifndef __has_feature
3540#define __has_feature(x) 0
3541#endif
3542#if __has_feature(blocks)
3543typedef enum CXChildVisitResult
3544 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3545
3546static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3547 CXClientData client_data) {
3548 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3549 return block(cursor, parent);
3550}
3551#else
3552// If we are compiled with a compiler that doesn't have native blocks support,
3553// define and call the block manually, so the
3554typedef struct _CXChildVisitResult
3555{
3556 void *isa;
3557 int flags;
3558 int reserved;
3559 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3560 CXCursor);
3561} *CXCursorVisitorBlock;
3562
3563static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3564 CXClientData client_data) {
3565 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3566 return block->invoke(block, cursor, parent);
3567}
3568#endif
3569
3570
3571unsigned clang_visitChildrenWithBlock(CXCursor parent,
3572 CXCursorVisitorBlock block) {
3573 return clang_visitChildren(parent, visitWithBlock, block);
3574}
3575
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003576static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003578 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003582 if (const ObjCPropertyImplDecl *PropImpl =
3583 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003591 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003594 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003595 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3599 // and returns different names. NamedDecl returns the class name and
3600 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003602
3603 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003604 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
3606 SmallString<1024> S;
3607 llvm::raw_svector_ostream os(S);
3608 ND->printName(os);
3609
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611}
3612
3613CXString clang_getCursorSpelling(CXCursor C) {
3614 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003615 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003616
3617 if (clang_isReference(C.kind)) {
3618 switch (C.kind) {
3619 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003620 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 }
3623 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003624 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 }
3627 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003628 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
3632 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003634 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 }
3636 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003637 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 assert(Type && "Missing type decl");
3639
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003640 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 getAsString());
3642 }
3643 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003644 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 assert(Template && "Missing template decl");
3646
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003647 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 }
3649
3650 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003651 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 assert(NS && "Missing namespace decl");
3653
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003654 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 }
3656
3657 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003658 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 assert(Field && "Missing member decl");
3660
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003661 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 }
3663
3664 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003665 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 assert(Label && "Missing label");
3667
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 }
3670
3671 case CXCursor_OverloadedDeclRef: {
3672 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3674 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003675 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003676 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003678 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003679 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 OverloadedTemplateStorage *Ovl
3681 = Storage.get<OverloadedTemplateStorage*>();
3682 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003683 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003684 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686
3687 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003688 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 assert(Var && "Missing variable decl");
3690
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693
3694 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 }
3697 }
3698
3699 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003700 const Expr *E = getCursorExpr(C);
3701
3702 if (C.kind == CXCursor_ObjCStringLiteral ||
3703 C.kind == CXCursor_StringLiteral) {
3704 const StringLiteral *SLit;
3705 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3706 SLit = OSL->getString();
3707 } else {
3708 SLit = cast<StringLiteral>(E);
3709 }
3710 SmallString<256> Buf;
3711 llvm::raw_svector_ostream OS(Buf);
3712 SLit->outputString(OS);
3713 return cxstring::createDup(OS.str());
3714 }
3715
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003716 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 if (D)
3718 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003719 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 }
3721
3722 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003723 const Stmt *S = getCursorStmt(C);
3724 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003726
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003727 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 }
3729
3730 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 ->getNameStart());
3733
3734 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 ->getNameStart());
3737
3738 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003739 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003740
3741 if (clang_isDeclaration(C.kind))
3742 return getDeclSpelling(getCursorDecl(C));
3743
3744 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003745 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003746 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 }
3748
3749 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003750 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003751 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 }
3753
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003754 if (C.kind == CXCursor_PackedAttr) {
3755 return cxstring::createRef("packed");
3756 }
3757
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003758 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003759}
3760
3761CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3762 unsigned pieceIndex,
3763 unsigned options) {
3764 if (clang_Cursor_isNull(C))
3765 return clang_getNullRange();
3766
3767 ASTContext &Ctx = getCursorContext(C);
3768
3769 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003770 const Stmt *S = getCursorStmt(C);
3771 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 if (pieceIndex > 0)
3773 return clang_getNullRange();
3774 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3775 }
3776
3777 return clang_getNullRange();
3778 }
3779
3780 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003781 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3783 if (pieceIndex >= ME->getNumSelectorLocs())
3784 return clang_getNullRange();
3785 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3786 }
3787 }
3788
3789 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3790 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003791 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3793 if (pieceIndex >= MD->getNumSelectorLocs())
3794 return clang_getNullRange();
3795 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3796 }
3797 }
3798
3799 if (C.kind == CXCursor_ObjCCategoryDecl ||
3800 C.kind == CXCursor_ObjCCategoryImplDecl) {
3801 if (pieceIndex > 0)
3802 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003803 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3805 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003806 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3808 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3809 }
3810
3811 if (C.kind == CXCursor_ModuleImportDecl) {
3812 if (pieceIndex > 0)
3813 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003814 if (const ImportDecl *ImportD =
3815 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3817 if (!Locs.empty())
3818 return cxloc::translateSourceRange(Ctx,
3819 SourceRange(Locs.front(), Locs.back()));
3820 }
3821 return clang_getNullRange();
3822 }
3823
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003824 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3825 C.kind == CXCursor_ConversionFunction) {
3826 if (pieceIndex > 0)
3827 return clang_getNullRange();
3828 if (const FunctionDecl *FD =
3829 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3830 DeclarationNameInfo FunctionName = FD->getNameInfo();
3831 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3832 }
3833 return clang_getNullRange();
3834 }
3835
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 // FIXME: A CXCursor_InclusionDirective should give the location of the
3837 // filename, but we don't keep track of this.
3838
3839 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3840 // but we don't keep track of this.
3841
3842 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3843 // but we don't keep track of this.
3844
3845 // Default handling, give the location of the cursor.
3846
3847 if (pieceIndex > 0)
3848 return clang_getNullRange();
3849
3850 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3851 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3852 return cxloc::translateSourceRange(Ctx, Loc);
3853}
3854
Eli Bendersky44a206f2014-07-31 18:04:56 +00003855CXString clang_Cursor_getMangling(CXCursor C) {
3856 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3857 return cxstring::createEmpty();
3858
Eli Bendersky44a206f2014-07-31 18:04:56 +00003859 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003860 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003861 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3862 return cxstring::createEmpty();
3863
Eli Bendersky79759592014-08-01 15:01:10 +00003864 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003865 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003866 ASTContext &Ctx = ND->getASTContext();
3867 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003868
Eli Bendersky79759592014-08-01 15:01:10 +00003869 std::string FrontendBuf;
3870 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3871 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003872
Eli Bendersky79759592014-08-01 15:01:10 +00003873 // Now apply backend mangling.
3874 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003875 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003876
3877 std::string FinalBuf;
3878 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003879 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3880 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003881
3882 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003883}
3884
Guy Benyei11169dd2012-12-18 14:30:41 +00003885CXString clang_getCursorDisplayName(CXCursor C) {
3886 if (!clang_isDeclaration(C.kind))
3887 return clang_getCursorSpelling(C);
3888
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003889 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003891 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003892
3893 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003894 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 D = FunTmpl->getTemplatedDecl();
3896
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003897 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 SmallString<64> Str;
3899 llvm::raw_svector_ostream OS(Str);
3900 OS << *Function;
3901 if (Function->getPrimaryTemplate())
3902 OS << "<>";
3903 OS << "(";
3904 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3905 if (I)
3906 OS << ", ";
3907 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3908 }
3909
3910 if (Function->isVariadic()) {
3911 if (Function->getNumParams())
3912 OS << ", ";
3913 OS << "...";
3914 }
3915 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003916 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 }
3918
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 SmallString<64> Str;
3921 llvm::raw_svector_ostream OS(Str);
3922 OS << *ClassTemplate;
3923 OS << "<";
3924 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3925 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3926 if (I)
3927 OS << ", ";
3928
3929 NamedDecl *Param = Params->getParam(I);
3930 if (Param->getIdentifier()) {
3931 OS << Param->getIdentifier()->getName();
3932 continue;
3933 }
3934
3935 // There is no parameter name, which makes this tricky. Try to come up
3936 // with something useful that isn't too long.
3937 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3938 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3939 else if (NonTypeTemplateParmDecl *NTTP
3940 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3941 OS << NTTP->getType().getAsString(Policy);
3942 else
3943 OS << "template<...> class";
3944 }
3945
3946 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003947 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 }
3949
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003950 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3952 // If the type was explicitly written, use that.
3953 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003954 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003955
Benjamin Kramer9170e912013-02-22 15:46:01 +00003956 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 llvm::raw_svector_ostream OS(Str);
3958 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003959 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 ClassSpec->getTemplateArgs().data(),
3961 ClassSpec->getTemplateArgs().size(),
3962 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003963 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 }
3965
3966 return clang_getCursorSpelling(C);
3967}
3968
3969CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3970 switch (Kind) {
3971 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004099 case CXCursor_ObjCSelfExpr:
4100 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004189 case CXCursor_SEHLeaveStmt:
4190 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004219 case CXCursor_PackedAttr:
4220 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004221 case CXCursor_PureAttr:
4222 return cxstring::createRef("attribute(pure)");
4223 case CXCursor_ConstAttr:
4224 return cxstring::createRef("attribute(const)");
4225 case CXCursor_NoDuplicateAttr:
4226 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004227 case CXCursor_CUDAConstantAttr:
4228 return cxstring::createRef("attribute(constant)");
4229 case CXCursor_CUDADeviceAttr:
4230 return cxstring::createRef("attribute(device)");
4231 case CXCursor_CUDAGlobalAttr:
4232 return cxstring::createRef("attribute(global)");
4233 case CXCursor_CUDAHostAttr:
4234 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004235 case CXCursor_CUDASharedAttr:
4236 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004285 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004286 return cxstring::createRef("OMPParallelDirective");
4287 case CXCursor_OMPSimdDirective:
4288 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004289 case CXCursor_OMPForDirective:
4290 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004291 case CXCursor_OMPForSimdDirective:
4292 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004293 case CXCursor_OMPSectionsDirective:
4294 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004295 case CXCursor_OMPSectionDirective:
4296 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004297 case CXCursor_OMPSingleDirective:
4298 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004299 case CXCursor_OMPMasterDirective:
4300 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004301 case CXCursor_OMPCriticalDirective:
4302 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004303 case CXCursor_OMPParallelForDirective:
4304 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004305 case CXCursor_OMPParallelForSimdDirective:
4306 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004307 case CXCursor_OMPParallelSectionsDirective:
4308 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004309 case CXCursor_OMPTaskDirective:
4310 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004311 case CXCursor_OMPTaskyieldDirective:
4312 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004313 case CXCursor_OMPBarrierDirective:
4314 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004315 case CXCursor_OMPTaskwaitDirective:
4316 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004317 case CXCursor_OMPTaskgroupDirective:
4318 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004319 case CXCursor_OMPFlushDirective:
4320 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004321 case CXCursor_OMPOrderedDirective:
4322 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004323 case CXCursor_OMPAtomicDirective:
4324 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004325 case CXCursor_OMPTargetDirective:
4326 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004327 case CXCursor_OMPTargetDataDirective:
4328 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004329 case CXCursor_OMPTeamsDirective:
4330 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004331 case CXCursor_OMPCancellationPointDirective:
4332 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004333 case CXCursor_OMPCancelDirective:
4334 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004335 case CXCursor_OverloadCandidate:
4336 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 }
4338
4339 llvm_unreachable("Unhandled CXCursorKind");
4340}
4341
4342struct GetCursorData {
4343 SourceLocation TokenBeginLoc;
4344 bool PointsAtMacroArgExpansion;
4345 bool VisitedObjCPropertyImplDecl;
4346 SourceLocation VisitedDeclaratorDeclStartLoc;
4347 CXCursor &BestCursor;
4348
4349 GetCursorData(SourceManager &SM,
4350 SourceLocation tokenBegin, CXCursor &outputCursor)
4351 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4352 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4353 VisitedObjCPropertyImplDecl = false;
4354 }
4355};
4356
4357static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4358 CXCursor parent,
4359 CXClientData client_data) {
4360 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4361 CXCursor *BestCursor = &Data->BestCursor;
4362
4363 // If we point inside a macro argument we should provide info of what the
4364 // token is so use the actual cursor, don't replace it with a macro expansion
4365 // cursor.
4366 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4367 return CXChildVisit_Recurse;
4368
4369 if (clang_isDeclaration(cursor.kind)) {
4370 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004371 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4373 if (MD->isImplicit())
4374 return CXChildVisit_Break;
4375
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004376 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4378 // Check that when we have multiple @class references in the same line,
4379 // that later ones do not override the previous ones.
4380 // If we have:
4381 // @class Foo, Bar;
4382 // source ranges for both start at '@', so 'Bar' will end up overriding
4383 // 'Foo' even though the cursor location was at 'Foo'.
4384 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4385 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004386 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4388 if (PrevID != ID &&
4389 !PrevID->isThisDeclarationADefinition() &&
4390 !ID->isThisDeclarationADefinition())
4391 return CXChildVisit_Break;
4392 }
4393
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004394 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4396 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4397 // Check that when we have multiple declarators in the same line,
4398 // that later ones do not override the previous ones.
4399 // If we have:
4400 // int Foo, Bar;
4401 // source ranges for both start at 'int', so 'Bar' will end up overriding
4402 // 'Foo' even though the cursor location was at 'Foo'.
4403 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4404 return CXChildVisit_Break;
4405 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4409 (void)PropImp;
4410 // Check that when we have multiple @synthesize in the same line,
4411 // that later ones do not override the previous ones.
4412 // If we have:
4413 // @synthesize Foo, Bar;
4414 // source ranges for both start at '@', so 'Bar' will end up overriding
4415 // 'Foo' even though the cursor location was at 'Foo'.
4416 if (Data->VisitedObjCPropertyImplDecl)
4417 return CXChildVisit_Break;
4418 Data->VisitedObjCPropertyImplDecl = true;
4419 }
4420 }
4421
4422 if (clang_isExpression(cursor.kind) &&
4423 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 // Avoid having the cursor of an expression replace the declaration cursor
4426 // when the expression source range overlaps the declaration range.
4427 // This can happen for C++ constructor expressions whose range generally
4428 // include the variable declaration, e.g.:
4429 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4430 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4431 D->getLocation() == Data->TokenBeginLoc)
4432 return CXChildVisit_Break;
4433 }
4434 }
4435
4436 // If our current best cursor is the construction of a temporary object,
4437 // don't replace that cursor with a type reference, because we want
4438 // clang_getCursor() to point at the constructor.
4439 if (clang_isExpression(BestCursor->kind) &&
4440 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4441 cursor.kind == CXCursor_TypeRef) {
4442 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4443 // as having the actual point on the type reference.
4444 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4445 return CXChildVisit_Recurse;
4446 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004447
4448 // If we already have an Objective-C superclass reference, don't
4449 // update it further.
4450 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4451 return CXChildVisit_Break;
4452
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 *BestCursor = cursor;
4454 return CXChildVisit_Recurse;
4455}
4456
4457CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004458 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004459 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004461 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004462
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004463 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4465
4466 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4467 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4468
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004469 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 CXFile SearchFile;
4471 unsigned SearchLine, SearchColumn;
4472 CXFile ResultFile;
4473 unsigned ResultLine, ResultColumn;
4474 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4475 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4476 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004477
4478 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4479 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004480 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004481 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 SearchFileName = clang_getFileName(SearchFile);
4483 ResultFileName = clang_getFileName(ResultFile);
4484 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4485 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004486 *Log << llvm::format("(%s:%d:%d) = %s",
4487 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4488 clang_getCString(KindSpelling))
4489 << llvm::format("(%s:%d:%d):%s%s",
4490 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4491 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 clang_disposeString(SearchFileName);
4493 clang_disposeString(ResultFileName);
4494 clang_disposeString(KindSpelling);
4495 clang_disposeString(USR);
4496
4497 CXCursor Definition = clang_getCursorDefinition(Result);
4498 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4499 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4500 CXString DefinitionKindSpelling
4501 = clang_getCursorKindSpelling(Definition.kind);
4502 CXFile DefinitionFile;
4503 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004504 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004505 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004507 *Log << llvm::format(" -> %s(%s:%d:%d)",
4508 clang_getCString(DefinitionKindSpelling),
4509 clang_getCString(DefinitionFileName),
4510 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 clang_disposeString(DefinitionFileName);
4512 clang_disposeString(DefinitionKindSpelling);
4513 }
4514 }
4515
4516 return Result;
4517}
4518
4519CXCursor clang_getNullCursor(void) {
4520 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4521}
4522
4523unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004524 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4525 // can't set consistently. For example, when visiting a DeclStmt we will set
4526 // it but we don't set it on the result of clang_getCursorDefinition for
4527 // a reference of the same declaration.
4528 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4529 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4530 // to provide that kind of info.
4531 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004532 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004533 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004534 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004535
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 return X == Y;
4537}
4538
4539unsigned clang_hashCursor(CXCursor C) {
4540 unsigned Index = 0;
4541 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4542 Index = 1;
4543
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004544 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 std::make_pair(C.kind, C.data[Index]));
4546}
4547
4548unsigned clang_isInvalid(enum CXCursorKind K) {
4549 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4550}
4551
4552unsigned clang_isDeclaration(enum CXCursorKind K) {
4553 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4554 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4555}
4556
4557unsigned clang_isReference(enum CXCursorKind K) {
4558 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4559}
4560
4561unsigned clang_isExpression(enum CXCursorKind K) {
4562 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4563}
4564
4565unsigned clang_isStatement(enum CXCursorKind K) {
4566 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4567}
4568
4569unsigned clang_isAttribute(enum CXCursorKind K) {
4570 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4571}
4572
4573unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4574 return K == CXCursor_TranslationUnit;
4575}
4576
4577unsigned clang_isPreprocessing(enum CXCursorKind K) {
4578 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4579}
4580
4581unsigned clang_isUnexposed(enum CXCursorKind K) {
4582 switch (K) {
4583 case CXCursor_UnexposedDecl:
4584 case CXCursor_UnexposedExpr:
4585 case CXCursor_UnexposedStmt:
4586 case CXCursor_UnexposedAttr:
4587 return true;
4588 default:
4589 return false;
4590 }
4591}
4592
4593CXCursorKind clang_getCursorKind(CXCursor C) {
4594 return C.kind;
4595}
4596
4597CXSourceLocation clang_getCursorLocation(CXCursor C) {
4598 if (clang_isReference(C.kind)) {
4599 switch (C.kind) {
4600 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004601 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 = getCursorObjCSuperClassRef(C);
4603 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4604 }
4605
4606 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004607 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 = getCursorObjCProtocolRef(C);
4609 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4610 }
4611
4612 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 = getCursorObjCClassRef(C);
4615 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4616 }
4617
4618 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004619 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4621 }
4622
4623 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 std::pair<const TemplateDecl *, SourceLocation> P =
4625 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4627 }
4628
4629 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004630 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4632 }
4633
4634 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004635 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4637 }
4638
4639 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004640 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4642 }
4643
4644 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004645 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 if (!BaseSpec)
4647 return clang_getNullLocation();
4648
4649 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4650 return cxloc::translateSourceLocation(getCursorContext(C),
4651 TSInfo->getTypeLoc().getBeginLoc());
4652
4653 return cxloc::translateSourceLocation(getCursorContext(C),
4654 BaseSpec->getLocStart());
4655 }
4656
4657 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004658 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4660 }
4661
4662 case CXCursor_OverloadedDeclRef:
4663 return cxloc::translateSourceLocation(getCursorContext(C),
4664 getCursorOverloadedDeclRef(C).second);
4665
4666 default:
4667 // FIXME: Need a way to enumerate all non-reference cases.
4668 llvm_unreachable("Missed a reference kind");
4669 }
4670 }
4671
4672 if (clang_isExpression(C.kind))
4673 return cxloc::translateSourceLocation(getCursorContext(C),
4674 getLocationFromExpr(getCursorExpr(C)));
4675
4676 if (clang_isStatement(C.kind))
4677 return cxloc::translateSourceLocation(getCursorContext(C),
4678 getCursorStmt(C)->getLocStart());
4679
4680 if (C.kind == CXCursor_PreprocessingDirective) {
4681 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4682 return cxloc::translateSourceLocation(getCursorContext(C), L);
4683 }
4684
4685 if (C.kind == CXCursor_MacroExpansion) {
4686 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004687 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 return cxloc::translateSourceLocation(getCursorContext(C), L);
4689 }
4690
4691 if (C.kind == CXCursor_MacroDefinition) {
4692 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4693 return cxloc::translateSourceLocation(getCursorContext(C), L);
4694 }
4695
4696 if (C.kind == CXCursor_InclusionDirective) {
4697 SourceLocation L
4698 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4699 return cxloc::translateSourceLocation(getCursorContext(C), L);
4700 }
4701
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004702 if (clang_isAttribute(C.kind)) {
4703 SourceLocation L
4704 = cxcursor::getCursorAttr(C)->getLocation();
4705 return cxloc::translateSourceLocation(getCursorContext(C), L);
4706 }
4707
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 if (!clang_isDeclaration(C.kind))
4709 return clang_getNullLocation();
4710
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (!D)
4713 return clang_getNullLocation();
4714
4715 SourceLocation Loc = D->getLocation();
4716 // FIXME: Multiple variables declared in a single declaration
4717 // currently lack the information needed to correctly determine their
4718 // ranges when accounting for the type-specifier. We use context
4719 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4720 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004721 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 if (!cxcursor::isFirstInDeclGroup(C))
4723 Loc = VD->getLocation();
4724 }
4725
4726 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004727 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 Loc = MD->getSelectorStartLoc();
4729
4730 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4731}
4732
4733} // end extern "C"
4734
4735CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4736 assert(TU);
4737
4738 // Guard against an invalid SourceLocation, or we may assert in one
4739 // of the following calls.
4740 if (SLoc.isInvalid())
4741 return clang_getNullCursor();
4742
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004743 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004744
4745 // Translate the given source location to make it point at the beginning of
4746 // the token under the cursor.
4747 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4748 CXXUnit->getASTContext().getLangOpts());
4749
4750 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4751 if (SLoc.isValid()) {
4752 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4753 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4754 /*VisitPreprocessorLast=*/true,
4755 /*VisitIncludedEntities=*/false,
4756 SourceLocation(SLoc));
4757 CursorVis.visitFileRegion();
4758 }
4759
4760 return Result;
4761}
4762
4763static SourceRange getRawCursorExtent(CXCursor C) {
4764 if (clang_isReference(C.kind)) {
4765 switch (C.kind) {
4766 case CXCursor_ObjCSuperClassRef:
4767 return getCursorObjCSuperClassRef(C).second;
4768
4769 case CXCursor_ObjCProtocolRef:
4770 return getCursorObjCProtocolRef(C).second;
4771
4772 case CXCursor_ObjCClassRef:
4773 return getCursorObjCClassRef(C).second;
4774
4775 case CXCursor_TypeRef:
4776 return getCursorTypeRef(C).second;
4777
4778 case CXCursor_TemplateRef:
4779 return getCursorTemplateRef(C).second;
4780
4781 case CXCursor_NamespaceRef:
4782 return getCursorNamespaceRef(C).second;
4783
4784 case CXCursor_MemberRef:
4785 return getCursorMemberRef(C).second;
4786
4787 case CXCursor_CXXBaseSpecifier:
4788 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4789
4790 case CXCursor_LabelRef:
4791 return getCursorLabelRef(C).second;
4792
4793 case CXCursor_OverloadedDeclRef:
4794 return getCursorOverloadedDeclRef(C).second;
4795
4796 case CXCursor_VariableRef:
4797 return getCursorVariableRef(C).second;
4798
4799 default:
4800 // FIXME: Need a way to enumerate all non-reference cases.
4801 llvm_unreachable("Missed a reference kind");
4802 }
4803 }
4804
4805 if (clang_isExpression(C.kind))
4806 return getCursorExpr(C)->getSourceRange();
4807
4808 if (clang_isStatement(C.kind))
4809 return getCursorStmt(C)->getSourceRange();
4810
4811 if (clang_isAttribute(C.kind))
4812 return getCursorAttr(C)->getRange();
4813
4814 if (C.kind == CXCursor_PreprocessingDirective)
4815 return cxcursor::getCursorPreprocessingDirective(C);
4816
4817 if (C.kind == CXCursor_MacroExpansion) {
4818 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004819 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 return TU->mapRangeFromPreamble(Range);
4821 }
4822
4823 if (C.kind == CXCursor_MacroDefinition) {
4824 ASTUnit *TU = getCursorASTUnit(C);
4825 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4826 return TU->mapRangeFromPreamble(Range);
4827 }
4828
4829 if (C.kind == CXCursor_InclusionDirective) {
4830 ASTUnit *TU = getCursorASTUnit(C);
4831 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4832 return TU->mapRangeFromPreamble(Range);
4833 }
4834
4835 if (C.kind == CXCursor_TranslationUnit) {
4836 ASTUnit *TU = getCursorASTUnit(C);
4837 FileID MainID = TU->getSourceManager().getMainFileID();
4838 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4839 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4840 return SourceRange(Start, End);
4841 }
4842
4843 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 if (!D)
4846 return SourceRange();
4847
4848 SourceRange R = D->getSourceRange();
4849 // FIXME: Multiple variables declared in a single declaration
4850 // currently lack the information needed to correctly determine their
4851 // ranges when accounting for the type-specifier. We use context
4852 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4853 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 if (!cxcursor::isFirstInDeclGroup(C))
4856 R.setBegin(VD->getLocation());
4857 }
4858 return R;
4859 }
4860 return SourceRange();
4861}
4862
4863/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4864/// the decl-specifier-seq for declarations.
4865static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4866 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 if (!D)
4869 return SourceRange();
4870
4871 SourceRange R = D->getSourceRange();
4872
4873 // Adjust the start of the location for declarations preceded by
4874 // declaration specifiers.
4875 SourceLocation StartLoc;
4876 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4877 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4878 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4881 StartLoc = TI->getTypeLoc().getLocStart();
4882 }
4883
4884 if (StartLoc.isValid() && R.getBegin().isValid() &&
4885 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4886 R.setBegin(StartLoc);
4887
4888 // FIXME: Multiple variables declared in a single declaration
4889 // currently lack the information needed to correctly determine their
4890 // ranges when accounting for the type-specifier. We use context
4891 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4892 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 if (!cxcursor::isFirstInDeclGroup(C))
4895 R.setBegin(VD->getLocation());
4896 }
4897
4898 return R;
4899 }
4900
4901 return getRawCursorExtent(C);
4902}
4903
4904extern "C" {
4905
4906CXSourceRange clang_getCursorExtent(CXCursor C) {
4907 SourceRange R = getRawCursorExtent(C);
4908 if (R.isInvalid())
4909 return clang_getNullRange();
4910
4911 return cxloc::translateSourceRange(getCursorContext(C), R);
4912}
4913
4914CXCursor clang_getCursorReferenced(CXCursor C) {
4915 if (clang_isInvalid(C.kind))
4916 return clang_getNullCursor();
4917
4918 CXTranslationUnit tu = getCursorTU(C);
4919 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004920 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 if (!D)
4922 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004923 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004925 if (const ObjCPropertyImplDecl *PropImpl =
4926 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4928 return MakeCXCursor(Property, tu);
4929
4930 return C;
4931 }
4932
4933 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004934 const Expr *E = getCursorExpr(C);
4935 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 if (D) {
4937 CXCursor declCursor = MakeCXCursor(D, tu);
4938 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4939 declCursor);
4940 return declCursor;
4941 }
4942
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004943 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 return MakeCursorOverloadedDeclRef(Ovl, tu);
4945
4946 return clang_getNullCursor();
4947 }
4948
4949 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004950 const Stmt *S = getCursorStmt(C);
4951 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 if (LabelDecl *label = Goto->getLabel())
4953 if (LabelStmt *labelS = label->getStmt())
4954 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4955
4956 return clang_getNullCursor();
4957 }
Richard Smith66a81862015-05-04 02:25:31 +00004958
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004960 if (const MacroDefinitionRecord *Def =
4961 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 return MakeMacroDefinitionCursor(Def, tu);
4963 }
4964
4965 if (!clang_isReference(C.kind))
4966 return clang_getNullCursor();
4967
4968 switch (C.kind) {
4969 case CXCursor_ObjCSuperClassRef:
4970 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4971
4972 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004973 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4974 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 return MakeCXCursor(Def, tu);
4976
4977 return MakeCXCursor(Prot, tu);
4978 }
4979
4980 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004981 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4982 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 return MakeCXCursor(Def, tu);
4984
4985 return MakeCXCursor(Class, tu);
4986 }
4987
4988 case CXCursor_TypeRef:
4989 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4990
4991 case CXCursor_TemplateRef:
4992 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4993
4994 case CXCursor_NamespaceRef:
4995 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4996
4997 case CXCursor_MemberRef:
4998 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4999
5000 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005001 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5003 tu ));
5004 }
5005
5006 case CXCursor_LabelRef:
5007 // FIXME: We end up faking the "parent" declaration here because we
5008 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005009 return MakeCXCursor(getCursorLabelRef(C).first,
5010 cxtu::getASTUnit(tu)->getASTContext()
5011 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 tu);
5013
5014 case CXCursor_OverloadedDeclRef:
5015 return C;
5016
5017 case CXCursor_VariableRef:
5018 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5019
5020 default:
5021 // We would prefer to enumerate all non-reference cursor kinds here.
5022 llvm_unreachable("Unhandled reference cursor kind");
5023 }
5024}
5025
5026CXCursor clang_getCursorDefinition(CXCursor C) {
5027 if (clang_isInvalid(C.kind))
5028 return clang_getNullCursor();
5029
5030 CXTranslationUnit TU = getCursorTU(C);
5031
5032 bool WasReference = false;
5033 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5034 C = clang_getCursorReferenced(C);
5035 WasReference = true;
5036 }
5037
5038 if (C.kind == CXCursor_MacroExpansion)
5039 return clang_getCursorReferenced(C);
5040
5041 if (!clang_isDeclaration(C.kind))
5042 return clang_getNullCursor();
5043
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (!D)
5046 return clang_getNullCursor();
5047
5048 switch (D->getKind()) {
5049 // Declaration kinds that don't really separate the notions of
5050 // declaration and definition.
5051 case Decl::Namespace:
5052 case Decl::Typedef:
5053 case Decl::TypeAlias:
5054 case Decl::TypeAliasTemplate:
5055 case Decl::TemplateTypeParm:
5056 case Decl::EnumConstant:
5057 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005058 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 case Decl::IndirectField:
5060 case Decl::ObjCIvar:
5061 case Decl::ObjCAtDefsField:
5062 case Decl::ImplicitParam:
5063 case Decl::ParmVar:
5064 case Decl::NonTypeTemplateParm:
5065 case Decl::TemplateTemplateParm:
5066 case Decl::ObjCCategoryImpl:
5067 case Decl::ObjCImplementation:
5068 case Decl::AccessSpec:
5069 case Decl::LinkageSpec:
5070 case Decl::ObjCPropertyImpl:
5071 case Decl::FileScopeAsm:
5072 case Decl::StaticAssert:
5073 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005074 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 case Decl::Label: // FIXME: Is this right??
5076 case Decl::ClassScopeFunctionSpecialization:
5077 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005078 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005079 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 return C;
5081
5082 // Declaration kinds that don't make any sense here, but are
5083 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005084 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005086 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 break;
5088
5089 // Declaration kinds for which the definition is not resolvable.
5090 case Decl::UnresolvedUsingTypename:
5091 case Decl::UnresolvedUsingValue:
5092 break;
5093
5094 case Decl::UsingDirective:
5095 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5096 TU);
5097
5098 case Decl::NamespaceAlias:
5099 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5100
5101 case Decl::Enum:
5102 case Decl::Record:
5103 case Decl::CXXRecord:
5104 case Decl::ClassTemplateSpecialization:
5105 case Decl::ClassTemplatePartialSpecialization:
5106 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5107 return MakeCXCursor(Def, TU);
5108 return clang_getNullCursor();
5109
5110 case Decl::Function:
5111 case Decl::CXXMethod:
5112 case Decl::CXXConstructor:
5113 case Decl::CXXDestructor:
5114 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005115 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005117 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 return clang_getNullCursor();
5119 }
5120
Larisse Voufo39a1e502013-08-06 01:03:05 +00005121 case Decl::Var:
5122 case Decl::VarTemplateSpecialization:
5123 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005125 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 return MakeCXCursor(Def, TU);
5127 return clang_getNullCursor();
5128 }
5129
5130 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005131 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5133 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5134 return clang_getNullCursor();
5135 }
5136
5137 case Decl::ClassTemplate: {
5138 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5139 ->getDefinition())
5140 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5141 TU);
5142 return clang_getNullCursor();
5143 }
5144
Larisse Voufo39a1e502013-08-06 01:03:05 +00005145 case Decl::VarTemplate: {
5146 if (VarDecl *Def =
5147 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5148 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5149 return clang_getNullCursor();
5150 }
5151
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case Decl::Using:
5153 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5154 D->getLocation(), TU);
5155
5156 case Decl::UsingShadow:
5157 return clang_getCursorDefinition(
5158 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5159 TU));
5160
5161 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005162 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 if (Method->isThisDeclarationADefinition())
5164 return C;
5165
5166 // Dig out the method definition in the associated
5167 // @implementation, if we have it.
5168 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005169 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5171 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5172 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5173 Method->isInstanceMethod()))
5174 if (Def->isThisDeclarationADefinition())
5175 return MakeCXCursor(Def, TU);
5176
5177 return clang_getNullCursor();
5178 }
5179
5180 case Decl::ObjCCategory:
5181 if (ObjCCategoryImplDecl *Impl
5182 = cast<ObjCCategoryDecl>(D)->getImplementation())
5183 return MakeCXCursor(Impl, TU);
5184 return clang_getNullCursor();
5185
5186 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005187 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 return MakeCXCursor(Def, TU);
5189 return clang_getNullCursor();
5190
5191 case Decl::ObjCInterface: {
5192 // There are two notions of a "definition" for an Objective-C
5193 // class: the interface and its implementation. When we resolved a
5194 // reference to an Objective-C class, produce the @interface as
5195 // the definition; when we were provided with the interface,
5196 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005197 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005199 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 return MakeCXCursor(Def, TU);
5201 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5202 return MakeCXCursor(Impl, TU);
5203 return clang_getNullCursor();
5204 }
5205
5206 case Decl::ObjCProperty:
5207 // FIXME: We don't really know where to find the
5208 // ObjCPropertyImplDecls that implement this property.
5209 return clang_getNullCursor();
5210
5211 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005212 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005214 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 return MakeCXCursor(Def, TU);
5216
5217 return clang_getNullCursor();
5218
5219 case Decl::Friend:
5220 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5221 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5222 return clang_getNullCursor();
5223
5224 case Decl::FriendTemplate:
5225 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5226 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5227 return clang_getNullCursor();
5228 }
5229
5230 return clang_getNullCursor();
5231}
5232
5233unsigned clang_isCursorDefinition(CXCursor C) {
5234 if (!clang_isDeclaration(C.kind))
5235 return 0;
5236
5237 return clang_getCursorDefinition(C) == C;
5238}
5239
5240CXCursor clang_getCanonicalCursor(CXCursor C) {
5241 if (!clang_isDeclaration(C.kind))
5242 return C;
5243
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005244 if (const Decl *D = getCursorDecl(C)) {
5245 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5247 return MakeCXCursor(CatD, getCursorTU(C));
5248
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005249 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5250 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 return MakeCXCursor(IFD, getCursorTU(C));
5252
5253 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5254 }
5255
5256 return C;
5257}
5258
5259int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5260 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5261}
5262
5263unsigned clang_getNumOverloadedDecls(CXCursor C) {
5264 if (C.kind != CXCursor_OverloadedDeclRef)
5265 return 0;
5266
5267 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005268 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 return E->getNumDecls();
5270
5271 if (OverloadedTemplateStorage *S
5272 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5273 return S->size();
5274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005275 const Decl *D = Storage.get<const Decl *>();
5276 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 return Using->shadow_size();
5278
5279 return 0;
5280}
5281
5282CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5283 if (cursor.kind != CXCursor_OverloadedDeclRef)
5284 return clang_getNullCursor();
5285
5286 if (index >= clang_getNumOverloadedDecls(cursor))
5287 return clang_getNullCursor();
5288
5289 CXTranslationUnit TU = getCursorTU(cursor);
5290 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005291 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 return MakeCXCursor(E->decls_begin()[index], TU);
5293
5294 if (OverloadedTemplateStorage *S
5295 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5296 return MakeCXCursor(S->begin()[index], TU);
5297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005298 const Decl *D = Storage.get<const Decl *>();
5299 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 // FIXME: This is, unfortunately, linear time.
5301 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5302 std::advance(Pos, index);
5303 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5304 }
5305
5306 return clang_getNullCursor();
5307}
5308
5309void clang_getDefinitionSpellingAndExtent(CXCursor C,
5310 const char **startBuf,
5311 const char **endBuf,
5312 unsigned *startLine,
5313 unsigned *startColumn,
5314 unsigned *endLine,
5315 unsigned *endColumn) {
5316 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005317 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5319
5320 SourceManager &SM = FD->getASTContext().getSourceManager();
5321 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5322 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5323 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5324 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5325 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5326 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5327}
5328
5329
5330CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5331 unsigned PieceIndex) {
5332 RefNamePieces Pieces;
5333
5334 switch (C.kind) {
5335 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005336 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5338 E->getQualifierLoc().getSourceRange());
5339 break;
5340
5341 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005342 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5344 E->getQualifierLoc().getSourceRange(),
5345 E->getOptionalExplicitTemplateArgs());
5346 break;
5347
5348 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005349 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005351 const Expr *Callee = OCE->getCallee();
5352 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 Callee = ICE->getSubExpr();
5354
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005355 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5357 DRE->getQualifierLoc().getSourceRange());
5358 }
5359 break;
5360
5361 default:
5362 break;
5363 }
5364
5365 if (Pieces.empty()) {
5366 if (PieceIndex == 0)
5367 return clang_getCursorExtent(C);
5368 } else if (PieceIndex < Pieces.size()) {
5369 SourceRange R = Pieces[PieceIndex];
5370 if (R.isValid())
5371 return cxloc::translateSourceRange(getCursorContext(C), R);
5372 }
5373
5374 return clang_getNullRange();
5375}
5376
5377void clang_enableStackTraces(void) {
5378 llvm::sys::PrintStackTraceOnErrorSignal();
5379}
5380
5381void clang_executeOnThread(void (*fn)(void*), void *user_data,
5382 unsigned stack_size) {
5383 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5384}
5385
5386} // end: extern "C"
5387
5388//===----------------------------------------------------------------------===//
5389// Token-based Operations.
5390//===----------------------------------------------------------------------===//
5391
5392/* CXToken layout:
5393 * int_data[0]: a CXTokenKind
5394 * int_data[1]: starting token location
5395 * int_data[2]: token length
5396 * int_data[3]: reserved
5397 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5398 * otherwise unused.
5399 */
5400extern "C" {
5401
5402CXTokenKind clang_getTokenKind(CXToken CXTok) {
5403 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5404}
5405
5406CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5407 switch (clang_getTokenKind(CXTok)) {
5408 case CXToken_Identifier:
5409 case CXToken_Keyword:
5410 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005411 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 ->getNameStart());
5413
5414 case CXToken_Literal: {
5415 // We have stashed the starting pointer in the ptr_data field. Use it.
5416 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005417 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 }
5419
5420 case CXToken_Punctuation:
5421 case CXToken_Comment:
5422 break;
5423 }
5424
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005425 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005426 LOG_BAD_TU(TU);
5427 return cxstring::createEmpty();
5428 }
5429
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 // We have to find the starting buffer pointer the hard way, by
5431 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005432 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005435
5436 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5437 std::pair<FileID, unsigned> LocInfo
5438 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5439 bool Invalid = false;
5440 StringRef Buffer
5441 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5442 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005443 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005444
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005445 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005446}
5447
5448CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005449 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005450 LOG_BAD_TU(TU);
5451 return clang_getNullLocation();
5452 }
5453
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005454 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 if (!CXXUnit)
5456 return clang_getNullLocation();
5457
5458 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5459 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5460}
5461
5462CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005463 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005464 LOG_BAD_TU(TU);
5465 return clang_getNullRange();
5466 }
5467
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005468 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 if (!CXXUnit)
5470 return clang_getNullRange();
5471
5472 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5473 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5474}
5475
5476static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5477 SmallVectorImpl<CXToken> &CXTokens) {
5478 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5479 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005480 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005482 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005483
5484 // Cannot tokenize across files.
5485 if (BeginLocInfo.first != EndLocInfo.first)
5486 return;
5487
5488 // Create a lexer
5489 bool Invalid = false;
5490 StringRef Buffer
5491 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5492 if (Invalid)
5493 return;
5494
5495 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5496 CXXUnit->getASTContext().getLangOpts(),
5497 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5498 Lex.SetCommentRetentionState(true);
5499
5500 // Lex tokens until we hit the end of the range.
5501 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5502 Token Tok;
5503 bool previousWasAt = false;
5504 do {
5505 // Lex the next token
5506 Lex.LexFromRawLexer(Tok);
5507 if (Tok.is(tok::eof))
5508 break;
5509
5510 // Initialize the CXToken.
5511 CXToken CXTok;
5512
5513 // - Common fields
5514 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5515 CXTok.int_data[2] = Tok.getLength();
5516 CXTok.int_data[3] = 0;
5517
5518 // - Kind-specific fields
5519 if (Tok.isLiteral()) {
5520 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005521 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 } else if (Tok.is(tok::raw_identifier)) {
5523 // Lookup the identifier to determine whether we have a keyword.
5524 IdentifierInfo *II
5525 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5526
5527 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5528 CXTok.int_data[0] = CXToken_Keyword;
5529 }
5530 else {
5531 CXTok.int_data[0] = Tok.is(tok::identifier)
5532 ? CXToken_Identifier
5533 : CXToken_Keyword;
5534 }
5535 CXTok.ptr_data = II;
5536 } else if (Tok.is(tok::comment)) {
5537 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005538 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005539 } else {
5540 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005541 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 }
5543 CXTokens.push_back(CXTok);
5544 previousWasAt = Tok.is(tok::at);
5545 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5546}
5547
5548void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5549 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005550 LOG_FUNC_SECTION {
5551 *Log << TU << ' ' << Range;
5552 }
5553
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005555 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 if (NumTokens)
5557 *NumTokens = 0;
5558
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005559 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005560 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005561 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005562 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005563
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005564 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 if (!CXXUnit || !Tokens || !NumTokens)
5566 return;
5567
5568 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5569
5570 SourceRange R = cxloc::translateCXSourceRange(Range);
5571 if (R.isInvalid())
5572 return;
5573
5574 SmallVector<CXToken, 32> CXTokens;
5575 getTokens(CXXUnit, R, CXTokens);
5576
5577 if (CXTokens.empty())
5578 return;
5579
5580 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5581 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5582 *NumTokens = CXTokens.size();
5583}
5584
5585void clang_disposeTokens(CXTranslationUnit TU,
5586 CXToken *Tokens, unsigned NumTokens) {
5587 free(Tokens);
5588}
5589
5590} // end: extern "C"
5591
5592//===----------------------------------------------------------------------===//
5593// Token annotation APIs.
5594//===----------------------------------------------------------------------===//
5595
Guy Benyei11169dd2012-12-18 14:30:41 +00005596static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5597 CXCursor parent,
5598 CXClientData client_data);
5599static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5600 CXClientData client_data);
5601
5602namespace {
5603class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 CXToken *Tokens;
5605 CXCursor *Cursors;
5606 unsigned NumTokens;
5607 unsigned TokIdx;
5608 unsigned PreprocessingTokIdx;
5609 CursorVisitor AnnotateVis;
5610 SourceManager &SrcMgr;
5611 bool HasContextSensitiveKeywords;
5612
5613 struct PostChildrenInfo {
5614 CXCursor Cursor;
5615 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005616 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 unsigned BeforeChildrenTokenIdx;
5618 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005619 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005620
5621 CXToken &getTok(unsigned Idx) {
5622 assert(Idx < NumTokens);
5623 return Tokens[Idx];
5624 }
5625 const CXToken &getTok(unsigned Idx) const {
5626 assert(Idx < NumTokens);
5627 return Tokens[Idx];
5628 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 bool MoreTokens() const { return TokIdx < NumTokens; }
5630 unsigned NextToken() const { return TokIdx; }
5631 void AdvanceToken() { ++TokIdx; }
5632 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005633 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 }
5635 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005636 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 }
5638 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005639 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 }
5641
5642 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005643 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 SourceRange);
5645
5646public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005647 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005648 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005649 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005650 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005651 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 AnnotateTokensVisitor, this,
5653 /*VisitPreprocessorLast=*/true,
5654 /*VisitIncludedEntities=*/false,
5655 RegionOfInterest,
5656 /*VisitDeclsOnly=*/false,
5657 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005658 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 HasContextSensitiveKeywords(false) { }
5660
5661 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5662 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5663 bool postVisitChildren(CXCursor cursor);
5664 void AnnotateTokens();
5665
5666 /// \brief Determine whether the annotator saw any cursors that have
5667 /// context-sensitive keywords.
5668 bool hasContextSensitiveKeywords() const {
5669 return HasContextSensitiveKeywords;
5670 }
5671
5672 ~AnnotateTokensWorker() {
5673 assert(PostChildrenInfos.empty());
5674 }
5675};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005676}
Guy Benyei11169dd2012-12-18 14:30:41 +00005677
5678void AnnotateTokensWorker::AnnotateTokens() {
5679 // Walk the AST within the region of interest, annotating tokens
5680 // along the way.
5681 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005682}
Guy Benyei11169dd2012-12-18 14:30:41 +00005683
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005684static inline void updateCursorAnnotation(CXCursor &Cursor,
5685 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005686 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005688 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005689}
5690
5691/// \brief It annotates and advances tokens with a cursor until the comparison
5692//// between the cursor location and the source range is the same as
5693/// \arg compResult.
5694///
5695/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5696/// Pass RangeOverlap to annotate tokens inside a range.
5697void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5698 RangeComparisonResult compResult,
5699 SourceRange range) {
5700 while (MoreTokens()) {
5701 const unsigned I = NextToken();
5702 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005703 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5704 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005705
5706 SourceLocation TokLoc = GetTokenLoc(I);
5707 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005708 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 AdvanceToken();
5710 continue;
5711 }
5712 break;
5713 }
5714}
5715
5716/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005717/// \returns true if it advanced beyond all macro tokens, false otherwise.
5718bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 CXCursor updateC,
5720 RangeComparisonResult compResult,
5721 SourceRange range) {
5722 assert(MoreTokens());
5723 assert(isFunctionMacroToken(NextToken()) &&
5724 "Should be called only for macro arg tokens");
5725
5726 // This works differently than annotateAndAdvanceTokens; because expanded
5727 // macro arguments can have arbitrary translation-unit source order, we do not
5728 // advance the token index one by one until a token fails the range test.
5729 // We only advance once past all of the macro arg tokens if all of them
5730 // pass the range test. If one of them fails we keep the token index pointing
5731 // at the start of the macro arg tokens so that the failing token will be
5732 // annotated by a subsequent annotation try.
5733
5734 bool atLeastOneCompFail = false;
5735
5736 unsigned I = NextToken();
5737 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5738 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5739 if (TokLoc.isFileID())
5740 continue; // not macro arg token, it's parens or comma.
5741 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5742 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5743 Cursors[I] = updateC;
5744 } else
5745 atLeastOneCompFail = true;
5746 }
5747
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005748 if (atLeastOneCompFail)
5749 return false;
5750
5751 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5752 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005753}
5754
5755enum CXChildVisitResult
5756AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 SourceRange cursorRange = getRawCursorExtent(cursor);
5758 if (cursorRange.isInvalid())
5759 return CXChildVisit_Recurse;
5760
5761 if (!HasContextSensitiveKeywords) {
5762 // Objective-C properties can have context-sensitive keywords.
5763 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005764 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5766 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5767 }
5768 // Objective-C methods can have context-sensitive keywords.
5769 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5770 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005771 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5773 if (Method->getObjCDeclQualifier())
5774 HasContextSensitiveKeywords = true;
5775 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005776 for (const auto *P : Method->params()) {
5777 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 HasContextSensitiveKeywords = true;
5779 break;
5780 }
5781 }
5782 }
5783 }
5784 }
5785 // C++ methods can have context-sensitive keywords.
5786 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005787 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5789 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5790 HasContextSensitiveKeywords = true;
5791 }
5792 }
5793 // C++ classes can have context-sensitive keywords.
5794 else if (cursor.kind == CXCursor_StructDecl ||
5795 cursor.kind == CXCursor_ClassDecl ||
5796 cursor.kind == CXCursor_ClassTemplate ||
5797 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005798 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005799 if (D->hasAttr<FinalAttr>())
5800 HasContextSensitiveKeywords = true;
5801 }
5802 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005803
5804 // Don't override a property annotation with its getter/setter method.
5805 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5806 parent.kind == CXCursor_ObjCPropertyDecl)
5807 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005808
5809 if (clang_isPreprocessing(cursor.kind)) {
5810 // Items in the preprocessing record are kept separate from items in
5811 // declarations, so we keep a separate token index.
5812 unsigned SavedTokIdx = TokIdx;
5813 TokIdx = PreprocessingTokIdx;
5814
5815 // Skip tokens up until we catch up to the beginning of the preprocessing
5816 // entry.
5817 while (MoreTokens()) {
5818 const unsigned I = NextToken();
5819 SourceLocation TokLoc = GetTokenLoc(I);
5820 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5821 case RangeBefore:
5822 AdvanceToken();
5823 continue;
5824 case RangeAfter:
5825 case RangeOverlap:
5826 break;
5827 }
5828 break;
5829 }
5830
5831 // Look at all of the tokens within this range.
5832 while (MoreTokens()) {
5833 const unsigned I = NextToken();
5834 SourceLocation TokLoc = GetTokenLoc(I);
5835 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5836 case RangeBefore:
5837 llvm_unreachable("Infeasible");
5838 case RangeAfter:
5839 break;
5840 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005841 // For macro expansions, just note where the beginning of the macro
5842 // expansion occurs.
5843 if (cursor.kind == CXCursor_MacroExpansion) {
5844 if (TokLoc == cursorRange.getBegin())
5845 Cursors[I] = cursor;
5846 AdvanceToken();
5847 break;
5848 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 // We may have already annotated macro names inside macro definitions.
5850 if (Cursors[I].kind != CXCursor_MacroExpansion)
5851 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 continue;
5854 }
5855 break;
5856 }
5857
5858 // Save the preprocessing token index; restore the non-preprocessing
5859 // token index.
5860 PreprocessingTokIdx = TokIdx;
5861 TokIdx = SavedTokIdx;
5862 return CXChildVisit_Recurse;
5863 }
5864
5865 if (cursorRange.isInvalid())
5866 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005867
5868 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 const enum CXCursorKind K = clang_getCursorKind(parent);
5871 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005872 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5873 // Attributes are annotated out-of-order, skip tokens until we reach it.
5874 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 ? clang_getNullCursor() : parent;
5876
5877 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5878
5879 // Avoid having the cursor of an expression "overwrite" the annotation of the
5880 // variable declaration that it belongs to.
5881 // This can happen for C++ constructor expressions whose range generally
5882 // include the variable declaration, e.g.:
5883 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005884 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005885 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005886 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 const unsigned I = NextToken();
5888 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5889 E->getLocStart() == D->getLocation() &&
5890 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005891 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 AdvanceToken();
5893 }
5894 }
5895 }
5896
5897 // Before recursing into the children keep some state that we are going
5898 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5899 // extra work after the child nodes are visited.
5900 // Note that we don't call VisitChildren here to avoid traversing statements
5901 // code-recursively which can blow the stack.
5902
5903 PostChildrenInfo Info;
5904 Info.Cursor = cursor;
5905 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005906 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 Info.BeforeChildrenTokenIdx = NextToken();
5908 PostChildrenInfos.push_back(Info);
5909
5910 return CXChildVisit_Recurse;
5911}
5912
5913bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5914 if (PostChildrenInfos.empty())
5915 return false;
5916 const PostChildrenInfo &Info = PostChildrenInfos.back();
5917 if (!clang_equalCursors(Info.Cursor, cursor))
5918 return false;
5919
5920 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5921 const unsigned AfterChildren = NextToken();
5922 SourceRange cursorRange = Info.CursorRange;
5923
5924 // Scan the tokens that are at the end of the cursor, but are not captured
5925 // but the child cursors.
5926 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5927
5928 // Scan the tokens that are at the beginning of the cursor, but are not
5929 // capture by the child cursors.
5930 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5931 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5932 break;
5933
5934 Cursors[I] = cursor;
5935 }
5936
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005937 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5938 // encountered the attribute cursor.
5939 if (clang_isAttribute(cursor.kind))
5940 TokIdx = Info.BeforeReachingCursorIdx;
5941
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 PostChildrenInfos.pop_back();
5943 return false;
5944}
5945
5946static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5947 CXCursor parent,
5948 CXClientData client_data) {
5949 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5950}
5951
5952static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5953 CXClientData client_data) {
5954 return static_cast<AnnotateTokensWorker*>(client_data)->
5955 postVisitChildren(cursor);
5956}
5957
5958namespace {
5959
5960/// \brief Uses the macro expansions in the preprocessing record to find
5961/// and mark tokens that are macro arguments. This info is used by the
5962/// AnnotateTokensWorker.
5963class MarkMacroArgTokensVisitor {
5964 SourceManager &SM;
5965 CXToken *Tokens;
5966 unsigned NumTokens;
5967 unsigned CurIdx;
5968
5969public:
5970 MarkMacroArgTokensVisitor(SourceManager &SM,
5971 CXToken *tokens, unsigned numTokens)
5972 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5973
5974 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5975 if (cursor.kind != CXCursor_MacroExpansion)
5976 return CXChildVisit_Continue;
5977
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005978 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 if (macroRange.getBegin() == macroRange.getEnd())
5980 return CXChildVisit_Continue; // it's not a function macro.
5981
5982 for (; CurIdx < NumTokens; ++CurIdx) {
5983 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5984 macroRange.getBegin()))
5985 break;
5986 }
5987
5988 if (CurIdx == NumTokens)
5989 return CXChildVisit_Break;
5990
5991 for (; CurIdx < NumTokens; ++CurIdx) {
5992 SourceLocation tokLoc = getTokenLoc(CurIdx);
5993 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5994 break;
5995
5996 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5997 }
5998
5999 if (CurIdx == NumTokens)
6000 return CXChildVisit_Break;
6001
6002 return CXChildVisit_Continue;
6003 }
6004
6005private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006006 CXToken &getTok(unsigned Idx) {
6007 assert(Idx < NumTokens);
6008 return Tokens[Idx];
6009 }
6010 const CXToken &getTok(unsigned Idx) const {
6011 assert(Idx < NumTokens);
6012 return Tokens[Idx];
6013 }
6014
Guy Benyei11169dd2012-12-18 14:30:41 +00006015 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006016 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 }
6018
6019 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6020 // The third field is reserved and currently not used. Use it here
6021 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006022 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 }
6024};
6025
6026} // end anonymous namespace
6027
6028static CXChildVisitResult
6029MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6030 CXClientData client_data) {
6031 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6032 parent);
6033}
6034
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006035/// \brief Used by \c annotatePreprocessorTokens.
6036/// \returns true if lexing was finished, false otherwise.
6037static bool lexNext(Lexer &Lex, Token &Tok,
6038 unsigned &NextIdx, unsigned NumTokens) {
6039 if (NextIdx >= NumTokens)
6040 return true;
6041
6042 ++NextIdx;
6043 Lex.LexFromRawLexer(Tok);
6044 if (Tok.is(tok::eof))
6045 return true;
6046
6047 return false;
6048}
6049
Guy Benyei11169dd2012-12-18 14:30:41 +00006050static void annotatePreprocessorTokens(CXTranslationUnit TU,
6051 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006052 CXCursor *Cursors,
6053 CXToken *Tokens,
6054 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006056
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006057 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006058 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6059 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006060 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006061 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006062 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006063
6064 if (BeginLocInfo.first != EndLocInfo.first)
6065 return;
6066
6067 StringRef Buffer;
6068 bool Invalid = false;
6069 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6070 if (Buffer.empty() || Invalid)
6071 return;
6072
6073 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6074 CXXUnit->getASTContext().getLangOpts(),
6075 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6076 Buffer.end());
6077 Lex.SetCommentRetentionState(true);
6078
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006079 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006080 // Lex tokens in raw mode until we hit the end of the range, to avoid
6081 // entering #includes or expanding macros.
6082 while (true) {
6083 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006084 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6085 break;
6086 unsigned TokIdx = NextIdx-1;
6087 assert(Tok.getLocation() ==
6088 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006089
6090 reprocess:
6091 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006092 // We have found a preprocessing directive. Annotate the tokens
6093 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 //
6095 // FIXME: Some simple tests here could identify macro definitions and
6096 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006097
6098 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006099 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6100 break;
6101
Craig Topper69186e72014-06-08 08:38:04 +00006102 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006103 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006104 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6105 break;
6106
6107 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006108 IdentifierInfo &II =
6109 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006110 SourceLocation MappedTokLoc =
6111 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6112 MI = getMacroInfo(II, MappedTokLoc, TU);
6113 }
6114 }
6115
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006116 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006118 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6119 finished = true;
6120 break;
6121 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006122 // If we are in a macro definition, check if the token was ever a
6123 // macro name and annotate it if that's the case.
6124 if (MI) {
6125 SourceLocation SaveLoc = Tok.getLocation();
6126 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006127 MacroDefinitionRecord *MacroDef =
6128 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006129 Tok.setLocation(SaveLoc);
6130 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006131 Cursors[NextIdx - 1] =
6132 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006133 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006134 } while (!Tok.isAtStartOfLine());
6135
6136 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6137 assert(TokIdx <= LastIdx);
6138 SourceLocation EndLoc =
6139 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6140 CXCursor Cursor =
6141 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6142
6143 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006144 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006145
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006146 if (finished)
6147 break;
6148 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 }
6151}
6152
6153// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006154static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6155 CXToken *Tokens, unsigned NumTokens,
6156 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006157 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6159 setThreadBackgroundPriority();
6160
6161 // Determine the region of interest, which contains all of the tokens.
6162 SourceRange RegionOfInterest;
6163 RegionOfInterest.setBegin(
6164 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6165 RegionOfInterest.setEnd(
6166 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6167 Tokens[NumTokens-1])));
6168
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 // Relex the tokens within the source range to look for preprocessing
6170 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006171 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006172
6173 // If begin location points inside a macro argument, set it to the expansion
6174 // location so we can have the full context when annotating semantically.
6175 {
6176 SourceManager &SM = CXXUnit->getSourceManager();
6177 SourceLocation Loc =
6178 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6179 if (Loc.isMacroID())
6180 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6181 }
6182
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6184 // Search and mark tokens that are macro argument expansions.
6185 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6186 Tokens, NumTokens);
6187 CursorVisitor MacroArgMarker(TU,
6188 MarkMacroArgTokensVisitorDelegate, &Visitor,
6189 /*VisitPreprocessorLast=*/true,
6190 /*VisitIncludedEntities=*/false,
6191 RegionOfInterest);
6192 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6193 }
6194
6195 // Annotate all of the source locations in the region of interest that map to
6196 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006198
6199 // FIXME: We use a ridiculous stack size here because the data-recursion
6200 // algorithm uses a large stack frame than the non-data recursive version,
6201 // and AnnotationTokensWorker currently transforms the data-recursion
6202 // algorithm back into a traditional recursion by explicitly calling
6203 // VisitChildren(). We will need to remove this explicit recursive call.
6204 W.AnnotateTokens();
6205
6206 // If we ran into any entities that involve context-sensitive keywords,
6207 // take another pass through the tokens to mark them as such.
6208 if (W.hasContextSensitiveKeywords()) {
6209 for (unsigned I = 0; I != NumTokens; ++I) {
6210 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6211 continue;
6212
6213 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6214 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006215 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006216 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6217 if (Property->getPropertyAttributesAsWritten() != 0 &&
6218 llvm::StringSwitch<bool>(II->getName())
6219 .Case("readonly", true)
6220 .Case("assign", true)
6221 .Case("unsafe_unretained", true)
6222 .Case("readwrite", true)
6223 .Case("retain", true)
6224 .Case("copy", true)
6225 .Case("nonatomic", true)
6226 .Case("atomic", true)
6227 .Case("getter", true)
6228 .Case("setter", true)
6229 .Case("strong", true)
6230 .Case("weak", true)
6231 .Default(false))
6232 Tokens[I].int_data[0] = CXToken_Keyword;
6233 }
6234 continue;
6235 }
6236
6237 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6238 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6239 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6240 if (llvm::StringSwitch<bool>(II->getName())
6241 .Case("in", true)
6242 .Case("out", true)
6243 .Case("inout", true)
6244 .Case("oneway", true)
6245 .Case("bycopy", true)
6246 .Case("byref", true)
6247 .Default(false))
6248 Tokens[I].int_data[0] = CXToken_Keyword;
6249 continue;
6250 }
6251
6252 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6253 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6254 Tokens[I].int_data[0] = CXToken_Keyword;
6255 continue;
6256 }
6257 }
6258 }
6259}
6260
6261extern "C" {
6262
6263void clang_annotateTokens(CXTranslationUnit TU,
6264 CXToken *Tokens, unsigned NumTokens,
6265 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006266 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006267 LOG_BAD_TU(TU);
6268 return;
6269 }
6270 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006271 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006272 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006273 }
6274
6275 LOG_FUNC_SECTION {
6276 *Log << TU << ' ';
6277 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6278 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6279 *Log << clang_getRange(bloc, eloc);
6280 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006281
6282 // Any token we don't specifically annotate will have a NULL cursor.
6283 CXCursor C = clang_getNullCursor();
6284 for (unsigned I = 0; I != NumTokens; ++I)
6285 Cursors[I] = C;
6286
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006287 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 if (!CXXUnit)
6289 return;
6290
6291 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006292
6293 auto AnnotateTokensImpl = [=]() {
6294 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6295 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006296 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006297 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006298 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6299 }
6300}
6301
6302} // end: extern "C"
6303
6304//===----------------------------------------------------------------------===//
6305// Operations for querying linkage of a cursor.
6306//===----------------------------------------------------------------------===//
6307
6308extern "C" {
6309CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6310 if (!clang_isDeclaration(cursor.kind))
6311 return CXLinkage_Invalid;
6312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006313 const Decl *D = cxcursor::getCursorDecl(cursor);
6314 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006315 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006316 case NoLinkage:
6317 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006318 case InternalLinkage: return CXLinkage_Internal;
6319 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6320 case ExternalLinkage: return CXLinkage_External;
6321 };
6322
6323 return CXLinkage_Invalid;
6324}
6325} // end: extern "C"
6326
6327//===----------------------------------------------------------------------===//
6328// Operations for querying language of a cursor.
6329//===----------------------------------------------------------------------===//
6330
6331static CXLanguageKind getDeclLanguage(const Decl *D) {
6332 if (!D)
6333 return CXLanguage_C;
6334
6335 switch (D->getKind()) {
6336 default:
6337 break;
6338 case Decl::ImplicitParam:
6339 case Decl::ObjCAtDefsField:
6340 case Decl::ObjCCategory:
6341 case Decl::ObjCCategoryImpl:
6342 case Decl::ObjCCompatibleAlias:
6343 case Decl::ObjCImplementation:
6344 case Decl::ObjCInterface:
6345 case Decl::ObjCIvar:
6346 case Decl::ObjCMethod:
6347 case Decl::ObjCProperty:
6348 case Decl::ObjCPropertyImpl:
6349 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006350 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006351 return CXLanguage_ObjC;
6352 case Decl::CXXConstructor:
6353 case Decl::CXXConversion:
6354 case Decl::CXXDestructor:
6355 case Decl::CXXMethod:
6356 case Decl::CXXRecord:
6357 case Decl::ClassTemplate:
6358 case Decl::ClassTemplatePartialSpecialization:
6359 case Decl::ClassTemplateSpecialization:
6360 case Decl::Friend:
6361 case Decl::FriendTemplate:
6362 case Decl::FunctionTemplate:
6363 case Decl::LinkageSpec:
6364 case Decl::Namespace:
6365 case Decl::NamespaceAlias:
6366 case Decl::NonTypeTemplateParm:
6367 case Decl::StaticAssert:
6368 case Decl::TemplateTemplateParm:
6369 case Decl::TemplateTypeParm:
6370 case Decl::UnresolvedUsingTypename:
6371 case Decl::UnresolvedUsingValue:
6372 case Decl::Using:
6373 case Decl::UsingDirective:
6374 case Decl::UsingShadow:
6375 return CXLanguage_CPlusPlus;
6376 }
6377
6378 return CXLanguage_C;
6379}
6380
6381extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006382
6383static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6384 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6385 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006386
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006387 switch (D->getAvailability()) {
6388 case AR_Available:
6389 case AR_NotYetIntroduced:
6390 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006391 return getCursorAvailabilityForDecl(
6392 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006393 return CXAvailability_Available;
6394
6395 case AR_Deprecated:
6396 return CXAvailability_Deprecated;
6397
6398 case AR_Unavailable:
6399 return CXAvailability_NotAvailable;
6400 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006401
6402 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006403}
6404
Guy Benyei11169dd2012-12-18 14:30:41 +00006405enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6406 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006407 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6408 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006409
6410 return CXAvailability_Available;
6411}
6412
6413static CXVersion convertVersion(VersionTuple In) {
6414 CXVersion Out = { -1, -1, -1 };
6415 if (In.empty())
6416 return Out;
6417
6418 Out.Major = In.getMajor();
6419
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006420 Optional<unsigned> Minor = In.getMinor();
6421 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 Out.Minor = *Minor;
6423 else
6424 return Out;
6425
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006426 Optional<unsigned> Subminor = In.getSubminor();
6427 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 Out.Subminor = *Subminor;
6429
6430 return Out;
6431}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006432
6433static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6434 int *always_deprecated,
6435 CXString *deprecated_message,
6436 int *always_unavailable,
6437 CXString *unavailable_message,
6438 CXPlatformAvailability *availability,
6439 int availability_size) {
6440 bool HadAvailAttr = false;
6441 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006442 for (auto A : D->attrs()) {
6443 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006444 HadAvailAttr = true;
6445 if (always_deprecated)
6446 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006447 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006448 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006449 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006450 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006451 continue;
6452 }
6453
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006454 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006455 HadAvailAttr = true;
6456 if (always_unavailable)
6457 *always_unavailable = 1;
6458 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006459 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006460 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6461 }
6462 continue;
6463 }
6464
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006465 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006466 HadAvailAttr = true;
6467 if (N < availability_size) {
6468 availability[N].Platform
6469 = cxstring::createDup(Avail->getPlatform()->getName());
6470 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6471 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6472 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6473 availability[N].Unavailable = Avail->getUnavailable();
6474 availability[N].Message = cxstring::createDup(Avail->getMessage());
6475 }
6476 ++N;
6477 }
6478 }
6479
6480 if (!HadAvailAttr)
6481 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6482 return getCursorPlatformAvailabilityForDecl(
6483 cast<Decl>(EnumConst->getDeclContext()),
6484 always_deprecated,
6485 deprecated_message,
6486 always_unavailable,
6487 unavailable_message,
6488 availability,
6489 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006490
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006491 return N;
6492}
6493
Guy Benyei11169dd2012-12-18 14:30:41 +00006494int clang_getCursorPlatformAvailability(CXCursor cursor,
6495 int *always_deprecated,
6496 CXString *deprecated_message,
6497 int *always_unavailable,
6498 CXString *unavailable_message,
6499 CXPlatformAvailability *availability,
6500 int availability_size) {
6501 if (always_deprecated)
6502 *always_deprecated = 0;
6503 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006504 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 if (always_unavailable)
6506 *always_unavailable = 0;
6507 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006508 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006509
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 if (!clang_isDeclaration(cursor.kind))
6511 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006513 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006514 if (!D)
6515 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006516
6517 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6518 deprecated_message,
6519 always_unavailable,
6520 unavailable_message,
6521 availability,
6522 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006523}
6524
6525void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6526 clang_disposeString(availability->Platform);
6527 clang_disposeString(availability->Message);
6528}
6529
6530CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6531 if (clang_isDeclaration(cursor.kind))
6532 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6533
6534 return CXLanguage_Invalid;
6535}
6536
6537 /// \brief If the given cursor is the "templated" declaration
6538 /// descibing a class or function template, return the class or
6539 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006540static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006541 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006542 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006544 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006545 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6546 return FunTmpl;
6547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006548 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006549 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6550 return ClassTmpl;
6551
6552 return D;
6553}
6554
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006555
6556enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6557 StorageClass sc = SC_None;
6558 const Decl *D = getCursorDecl(C);
6559 if (D) {
6560 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6561 sc = FD->getStorageClass();
6562 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6563 sc = VD->getStorageClass();
6564 } else {
6565 return CX_SC_Invalid;
6566 }
6567 } else {
6568 return CX_SC_Invalid;
6569 }
6570 switch (sc) {
6571 case SC_None:
6572 return CX_SC_None;
6573 case SC_Extern:
6574 return CX_SC_Extern;
6575 case SC_Static:
6576 return CX_SC_Static;
6577 case SC_PrivateExtern:
6578 return CX_SC_PrivateExtern;
6579 case SC_OpenCLWorkGroupLocal:
6580 return CX_SC_OpenCLWorkGroupLocal;
6581 case SC_Auto:
6582 return CX_SC_Auto;
6583 case SC_Register:
6584 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006585 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006586 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006587}
6588
Guy Benyei11169dd2012-12-18 14:30:41 +00006589CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6590 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006591 if (const Decl *D = getCursorDecl(cursor)) {
6592 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 if (!DC)
6594 return clang_getNullCursor();
6595
6596 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6597 getCursorTU(cursor));
6598 }
6599 }
6600
6601 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006602 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 return MakeCXCursor(D, getCursorTU(cursor));
6604 }
6605
6606 return clang_getNullCursor();
6607}
6608
6609CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6610 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006611 if (const Decl *D = getCursorDecl(cursor)) {
6612 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006613 if (!DC)
6614 return clang_getNullCursor();
6615
6616 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6617 getCursorTU(cursor));
6618 }
6619 }
6620
6621 // FIXME: Note that we can't easily compute the lexical context of a
6622 // statement or expression, so we return nothing.
6623 return clang_getNullCursor();
6624}
6625
6626CXFile clang_getIncludedFile(CXCursor cursor) {
6627 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006628 return nullptr;
6629
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006630 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006631 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006632}
6633
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006634unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6635 if (C.kind != CXCursor_ObjCPropertyDecl)
6636 return CXObjCPropertyAttr_noattr;
6637
6638 unsigned Result = CXObjCPropertyAttr_noattr;
6639 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6640 ObjCPropertyDecl::PropertyAttributeKind Attr =
6641 PD->getPropertyAttributesAsWritten();
6642
6643#define SET_CXOBJCPROP_ATTR(A) \
6644 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6645 Result |= CXObjCPropertyAttr_##A
6646 SET_CXOBJCPROP_ATTR(readonly);
6647 SET_CXOBJCPROP_ATTR(getter);
6648 SET_CXOBJCPROP_ATTR(assign);
6649 SET_CXOBJCPROP_ATTR(readwrite);
6650 SET_CXOBJCPROP_ATTR(retain);
6651 SET_CXOBJCPROP_ATTR(copy);
6652 SET_CXOBJCPROP_ATTR(nonatomic);
6653 SET_CXOBJCPROP_ATTR(setter);
6654 SET_CXOBJCPROP_ATTR(atomic);
6655 SET_CXOBJCPROP_ATTR(weak);
6656 SET_CXOBJCPROP_ATTR(strong);
6657 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6658#undef SET_CXOBJCPROP_ATTR
6659
6660 return Result;
6661}
6662
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006663unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6664 if (!clang_isDeclaration(C.kind))
6665 return CXObjCDeclQualifier_None;
6666
6667 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6668 const Decl *D = getCursorDecl(C);
6669 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6670 QT = MD->getObjCDeclQualifier();
6671 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6672 QT = PD->getObjCDeclQualifier();
6673 if (QT == Decl::OBJC_TQ_None)
6674 return CXObjCDeclQualifier_None;
6675
6676 unsigned Result = CXObjCDeclQualifier_None;
6677 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6678 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6679 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6680 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6681 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6682 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6683
6684 return Result;
6685}
6686
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006687unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6688 if (!clang_isDeclaration(C.kind))
6689 return 0;
6690
6691 const Decl *D = getCursorDecl(C);
6692 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6693 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6694 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6695 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6696
6697 return 0;
6698}
6699
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006700unsigned clang_Cursor_isVariadic(CXCursor C) {
6701 if (!clang_isDeclaration(C.kind))
6702 return 0;
6703
6704 const Decl *D = getCursorDecl(C);
6705 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6706 return FD->isVariadic();
6707 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6708 return MD->isVariadic();
6709
6710 return 0;
6711}
6712
Guy Benyei11169dd2012-12-18 14:30:41 +00006713CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6714 if (!clang_isDeclaration(C.kind))
6715 return clang_getNullRange();
6716
6717 const Decl *D = getCursorDecl(C);
6718 ASTContext &Context = getCursorContext(C);
6719 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6720 if (!RC)
6721 return clang_getNullRange();
6722
6723 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6724}
6725
6726CXString clang_Cursor_getRawCommentText(CXCursor C) {
6727 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006728 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006729
6730 const Decl *D = getCursorDecl(C);
6731 ASTContext &Context = getCursorContext(C);
6732 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6733 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6734 StringRef();
6735
6736 // Don't duplicate the string because RawText points directly into source
6737 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006738 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006739}
6740
6741CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6742 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006743 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006744
6745 const Decl *D = getCursorDecl(C);
6746 const ASTContext &Context = getCursorContext(C);
6747 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6748
6749 if (RC) {
6750 StringRef BriefText = RC->getBriefText(Context);
6751
6752 // Don't duplicate the string because RawComment ensures that this memory
6753 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006754 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006755 }
6756
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006757 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006758}
6759
Guy Benyei11169dd2012-12-18 14:30:41 +00006760CXModule clang_Cursor_getModule(CXCursor C) {
6761 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006762 if (const ImportDecl *ImportD =
6763 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006764 return ImportD->getImportedModule();
6765 }
6766
Craig Topper69186e72014-06-08 08:38:04 +00006767 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006768}
6769
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006770CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6771 if (isNotUsableTU(TU)) {
6772 LOG_BAD_TU(TU);
6773 return nullptr;
6774 }
6775 if (!File)
6776 return nullptr;
6777 FileEntry *FE = static_cast<FileEntry *>(File);
6778
6779 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6780 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6781 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6782
Richard Smithfeb54b62014-10-23 02:01:19 +00006783 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006784}
6785
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006786CXFile clang_Module_getASTFile(CXModule CXMod) {
6787 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006788 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006789 Module *Mod = static_cast<Module*>(CXMod);
6790 return const_cast<FileEntry *>(Mod->getASTFile());
6791}
6792
Guy Benyei11169dd2012-12-18 14:30:41 +00006793CXModule clang_Module_getParent(CXModule CXMod) {
6794 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006795 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 Module *Mod = static_cast<Module*>(CXMod);
6797 return Mod->Parent;
6798}
6799
6800CXString clang_Module_getName(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->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006805}
6806
6807CXString clang_Module_getFullName(CXModule CXMod) {
6808 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006809 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006810 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006811 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006812}
6813
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006814int clang_Module_isSystem(CXModule CXMod) {
6815 if (!CXMod)
6816 return 0;
6817 Module *Mod = static_cast<Module*>(CXMod);
6818 return Mod->IsSystem;
6819}
6820
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006821unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6822 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006823 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006824 LOG_BAD_TU(TU);
6825 return 0;
6826 }
6827 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 return 0;
6829 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006830 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6831 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6832 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006833}
6834
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006835CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6836 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006837 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006838 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006839 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006840 }
6841 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006842 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006843 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006844 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006845
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006846 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6847 if (Index < TopHeaders.size())
6848 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006849
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006851}
6852
6853} // end: extern "C"
6854
6855//===----------------------------------------------------------------------===//
6856// C++ AST instrospection.
6857//===----------------------------------------------------------------------===//
6858
6859extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006860unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6861 if (!clang_isDeclaration(C.kind))
6862 return 0;
6863
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006864 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006865 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006866 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006867 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6868}
6869
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006870unsigned clang_CXXMethod_isConst(CXCursor C) {
6871 if (!clang_isDeclaration(C.kind))
6872 return 0;
6873
6874 const Decl *D = cxcursor::getCursorDecl(C);
6875 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006876 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006877 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6878}
6879
Guy Benyei11169dd2012-12-18 14:30:41 +00006880unsigned clang_CXXMethod_isStatic(CXCursor C) {
6881 if (!clang_isDeclaration(C.kind))
6882 return 0;
6883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006884 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006885 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006886 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 return (Method && Method->isStatic()) ? 1 : 0;
6888}
6889
6890unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6891 if (!clang_isDeclaration(C.kind))
6892 return 0;
6893
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006894 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006895 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006896 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 return (Method && Method->isVirtual()) ? 1 : 0;
6898}
6899} // end: extern "C"
6900
6901//===----------------------------------------------------------------------===//
6902// Attribute introspection.
6903//===----------------------------------------------------------------------===//
6904
6905extern "C" {
6906CXType clang_getIBOutletCollectionType(CXCursor C) {
6907 if (C.kind != CXCursor_IBOutletCollectionAttr)
6908 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6909
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006910 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006911 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6912
6913 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6914}
6915} // end: extern "C"
6916
6917//===----------------------------------------------------------------------===//
6918// Inspecting memory usage.
6919//===----------------------------------------------------------------------===//
6920
6921typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6922
6923static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6924 enum CXTUResourceUsageKind k,
6925 unsigned long amount) {
6926 CXTUResourceUsageEntry entry = { k, amount };
6927 entries.push_back(entry);
6928}
6929
6930extern "C" {
6931
6932const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6933 const char *str = "";
6934 switch (kind) {
6935 case CXTUResourceUsage_AST:
6936 str = "ASTContext: expressions, declarations, and types";
6937 break;
6938 case CXTUResourceUsage_Identifiers:
6939 str = "ASTContext: identifiers";
6940 break;
6941 case CXTUResourceUsage_Selectors:
6942 str = "ASTContext: selectors";
6943 break;
6944 case CXTUResourceUsage_GlobalCompletionResults:
6945 str = "Code completion: cached global results";
6946 break;
6947 case CXTUResourceUsage_SourceManagerContentCache:
6948 str = "SourceManager: content cache allocator";
6949 break;
6950 case CXTUResourceUsage_AST_SideTables:
6951 str = "ASTContext: side tables";
6952 break;
6953 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6954 str = "SourceManager: malloc'ed memory buffers";
6955 break;
6956 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6957 str = "SourceManager: mmap'ed memory buffers";
6958 break;
6959 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6960 str = "ExternalASTSource: malloc'ed memory buffers";
6961 break;
6962 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6963 str = "ExternalASTSource: mmap'ed memory buffers";
6964 break;
6965 case CXTUResourceUsage_Preprocessor:
6966 str = "Preprocessor: malloc'ed memory";
6967 break;
6968 case CXTUResourceUsage_PreprocessingRecord:
6969 str = "Preprocessor: PreprocessingRecord";
6970 break;
6971 case CXTUResourceUsage_SourceManager_DataStructures:
6972 str = "SourceManager: data structures and tables";
6973 break;
6974 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6975 str = "Preprocessor: header search tables";
6976 break;
6977 }
6978 return str;
6979}
6980
6981CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006982 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006983 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006984 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 return usage;
6986 }
6987
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006988 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006989 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006990 ASTContext &astContext = astUnit->getASTContext();
6991
6992 // How much memory is used by AST nodes and types?
6993 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6994 (unsigned long) astContext.getASTAllocatedMemory());
6995
6996 // How much memory is used by identifiers?
6997 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6998 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6999
7000 // How much memory is used for selectors?
7001 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7002 (unsigned long) astContext.Selectors.getTotalMemory());
7003
7004 // How much memory is used by ASTContext's side tables?
7005 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7006 (unsigned long) astContext.getSideTableAllocatedMemory());
7007
7008 // How much memory is used for caching global code completion results?
7009 unsigned long completionBytes = 0;
7010 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007011 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007012 completionBytes = completionAllocator->getTotalMemory();
7013 }
7014 createCXTUResourceUsageEntry(*entries,
7015 CXTUResourceUsage_GlobalCompletionResults,
7016 completionBytes);
7017
7018 // How much memory is being used by SourceManager's content cache?
7019 createCXTUResourceUsageEntry(*entries,
7020 CXTUResourceUsage_SourceManagerContentCache,
7021 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7022
7023 // How much memory is being used by the MemoryBuffer's in SourceManager?
7024 const SourceManager::MemoryBufferSizes &srcBufs =
7025 astUnit->getSourceManager().getMemoryBufferSizes();
7026
7027 createCXTUResourceUsageEntry(*entries,
7028 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7029 (unsigned long) srcBufs.malloc_bytes);
7030 createCXTUResourceUsageEntry(*entries,
7031 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7032 (unsigned long) srcBufs.mmap_bytes);
7033 createCXTUResourceUsageEntry(*entries,
7034 CXTUResourceUsage_SourceManager_DataStructures,
7035 (unsigned long) astContext.getSourceManager()
7036 .getDataStructureSizes());
7037
7038 // How much memory is being used by the ExternalASTSource?
7039 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7040 const ExternalASTSource::MemoryBufferSizes &sizes =
7041 esrc->getMemoryBufferSizes();
7042
7043 createCXTUResourceUsageEntry(*entries,
7044 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7045 (unsigned long) sizes.malloc_bytes);
7046 createCXTUResourceUsageEntry(*entries,
7047 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7048 (unsigned long) sizes.mmap_bytes);
7049 }
7050
7051 // How much memory is being used by the Preprocessor?
7052 Preprocessor &pp = astUnit->getPreprocessor();
7053 createCXTUResourceUsageEntry(*entries,
7054 CXTUResourceUsage_Preprocessor,
7055 pp.getTotalMemory());
7056
7057 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7058 createCXTUResourceUsageEntry(*entries,
7059 CXTUResourceUsage_PreprocessingRecord,
7060 pRec->getTotalMemory());
7061 }
7062
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_Preprocessor_HeaderSearch,
7065 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007066
Guy Benyei11169dd2012-12-18 14:30:41 +00007067 CXTUResourceUsage usage = { (void*) entries.get(),
7068 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007069 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007070 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007071 return usage;
7072}
7073
7074void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7075 if (usage.data)
7076 delete (MemUsageEntries*) usage.data;
7077}
7078
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007079CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7080 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007081 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007082 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007083
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007084 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007085 LOG_BAD_TU(TU);
7086 return skipped;
7087 }
7088
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007089 if (!file)
7090 return skipped;
7091
7092 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7093 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7094 if (!ppRec)
7095 return skipped;
7096
7097 ASTContext &Ctx = astUnit->getASTContext();
7098 SourceManager &sm = Ctx.getSourceManager();
7099 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7100 FileID wantedFileID = sm.translateFile(fileEntry);
7101
7102 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7103 std::vector<SourceRange> wantedRanges;
7104 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7105 i != ei; ++i) {
7106 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7107 wantedRanges.push_back(*i);
7108 }
7109
7110 skipped->count = wantedRanges.size();
7111 skipped->ranges = new CXSourceRange[skipped->count];
7112 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7113 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7114
7115 return skipped;
7116}
7117
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007118void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7119 if (ranges) {
7120 delete[] ranges->ranges;
7121 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007122 }
7123}
7124
Guy Benyei11169dd2012-12-18 14:30:41 +00007125} // end extern "C"
7126
7127void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7128 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7129 for (unsigned I = 0; I != Usage.numEntries; ++I)
7130 fprintf(stderr, " %s: %lu\n",
7131 clang_getTUResourceUsageName(Usage.entries[I].kind),
7132 Usage.entries[I].amount);
7133
7134 clang_disposeCXTUResourceUsage(Usage);
7135}
7136
7137//===----------------------------------------------------------------------===//
7138// Misc. utility functions.
7139//===----------------------------------------------------------------------===//
7140
7141/// Default to using an 8 MB stack size on "safety" threads.
7142static unsigned SafetyStackThreadSize = 8 << 20;
7143
7144namespace clang {
7145
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007146bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007147 unsigned Size) {
7148 if (!Size)
7149 Size = GetSafetyThreadStackSize();
7150 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007151 return CRC.RunSafelyOnThread(Fn, Size);
7152 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007153}
7154
7155unsigned GetSafetyThreadStackSize() {
7156 return SafetyStackThreadSize;
7157}
7158
7159void SetSafetyThreadStackSize(unsigned Value) {
7160 SafetyStackThreadSize = Value;
7161}
7162
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007163}
Guy Benyei11169dd2012-12-18 14:30:41 +00007164
7165void clang::setThreadBackgroundPriority() {
7166 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7167 return;
7168
Alp Toker1a86ad22014-07-06 06:24:00 +00007169#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007170 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7171#endif
7172}
7173
7174void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7175 if (!Unit)
7176 return;
7177
7178 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7179 DEnd = Unit->stored_diag_end();
7180 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007181 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007182 CXString Msg = clang_formatDiagnostic(&Diag,
7183 clang_defaultDiagnosticDisplayOptions());
7184 fprintf(stderr, "%s\n", clang_getCString(Msg));
7185 clang_disposeString(Msg);
7186 }
7187#ifdef LLVM_ON_WIN32
7188 // On Windows, force a flush, since there may be multiple copies of
7189 // stderr and stdout in the file system, all with different buffers
7190 // but writing to the same device.
7191 fflush(stderr);
7192#endif
7193}
7194
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007195MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7196 SourceLocation MacroDefLoc,
7197 CXTranslationUnit TU){
7198 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007199 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007200 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007201 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007202
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007203 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007204 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007205 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007206 if (MD) {
7207 for (MacroDirective::DefInfo
7208 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7209 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7210 return Def.getMacroInfo();
7211 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007212 }
7213
Craig Topper69186e72014-06-08 08:38:04 +00007214 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007215}
7216
Richard Smith66a81862015-05-04 02:25:31 +00007217const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007218 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007219 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007220 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007221 const IdentifierInfo *II = MacroDef->getName();
7222 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007223 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224
7225 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7226}
7227
Richard Smith66a81862015-05-04 02:25:31 +00007228MacroDefinitionRecord *
7229cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7230 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007232 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007233 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007234 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007235
7236 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007237 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007238 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7239 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007240 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241
7242 // Check that the token is inside the definition and not its argument list.
7243 SourceManager &SM = Unit->getSourceManager();
7244 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007245 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007246 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007247 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007248
7249 Preprocessor &PP = Unit->getPreprocessor();
7250 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7251 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007252 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007253
Alp Toker2d57cea2014-05-17 04:53:25 +00007254 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007255 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007256 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257
7258 // Check that the identifier is not one of the macro arguments.
7259 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007260 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261
Richard Smith20e883e2015-04-29 23:20:19 +00007262 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007263 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007264 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007265
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007266 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007267}
7268
Richard Smith66a81862015-05-04 02:25:31 +00007269MacroDefinitionRecord *
7270cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7271 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007272 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007273 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007274
7275 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007276 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007277 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278 Preprocessor &PP = Unit->getPreprocessor();
7279 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007280 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007281 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7282 Token Tok;
7283 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007284 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007285
7286 return checkForMacroInMacroDefinition(MI, Tok, TU);
7287}
7288
Guy Benyei11169dd2012-12-18 14:30:41 +00007289extern "C" {
7290
7291CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007292 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007293}
7294
7295} // end: extern "C"
7296
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007297Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7298 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007299 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007300 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007301 if (Unit->isMainFileAST())
7302 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007303 return *this;
7304 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007305 } else {
7306 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007307 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007308 return *this;
7309}
7310
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007311Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7312 *this << FE->getName();
7313 return *this;
7314}
7315
7316Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7317 CXString cursorName = clang_getCursorDisplayName(cursor);
7318 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7319 clang_disposeString(cursorName);
7320 return *this;
7321}
7322
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007323Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7324 CXFile File;
7325 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007326 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007327 CXString FileName = clang_getFileName(File);
7328 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7329 clang_disposeString(FileName);
7330 return *this;
7331}
7332
7333Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7334 CXSourceLocation BLoc = clang_getRangeStart(range);
7335 CXSourceLocation ELoc = clang_getRangeEnd(range);
7336
7337 CXFile BFile;
7338 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007339 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007340
7341 CXFile EFile;
7342 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007343 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007344
7345 CXString BFileName = clang_getFileName(BFile);
7346 if (BFile == EFile) {
7347 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7348 BLine, BColumn, ELine, EColumn);
7349 } else {
7350 CXString EFileName = clang_getFileName(EFile);
7351 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7352 BLine, BColumn)
7353 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7354 ELine, EColumn);
7355 clang_disposeString(EFileName);
7356 }
7357 clang_disposeString(BFileName);
7358 return *this;
7359}
7360
7361Logger &cxindex::Logger::operator<<(CXString Str) {
7362 *this << clang_getCString(Str);
7363 return *this;
7364}
7365
7366Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7367 LogOS << Fmt;
7368 return *this;
7369}
7370
Chandler Carruth37ad2582014-06-27 15:14:39 +00007371static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7372
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007373cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007374 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007375
7376 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7377
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007378 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007379 OS << "[libclang:" << Name << ':';
7380
Alp Toker1a86ad22014-07-06 06:24:00 +00007381#ifdef USE_DARWIN_THREADS
7382 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007383 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7384 OS << tid << ':';
7385#endif
7386
7387 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7388 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007389 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007390
7391 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007392 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007393 OS << "--------------------------------------------------\n";
7394 }
7395}