blob: 57bea9927dbcef2620f641bf6f7a72ce0df1c264 [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"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1a86ad22014-07-06 06:24:00 +000056#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
57#define USE_DARWIN_THREADS
58#endif
59
60#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061#include <pthread.h>
62#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000063
64using namespace clang;
65using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000066using namespace clang::cxtu;
67using namespace clang::cxindex;
68
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000069CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
70 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000071 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000072 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000073 CXTranslationUnit D = new CXTranslationUnitImpl();
74 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000076 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000077 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000078 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 return D;
81}
82
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000083bool cxtu::isASTReadError(ASTUnit *AU) {
84 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
85 DEnd = AU->stored_diag_end();
86 D != DEnd; ++D) {
87 if (D->getLevel() >= DiagnosticsEngine::Error &&
88 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
89 diag::DiagCat_AST_Deserialization_Issue)
90 return true;
91 }
92 return false;
93}
94
Guy Benyei11169dd2012-12-18 14:30:41 +000095cxtu::CXTUOwner::~CXTUOwner() {
96 if (TU)
97 clang_disposeTranslationUnit(TU);
98}
99
100/// \brief Compare two source ranges to determine their relative position in
101/// the translation unit.
102static RangeComparisonResult RangeCompare(SourceManager &SM,
103 SourceRange R1,
104 SourceRange R2) {
105 assert(R1.isValid() && "First range is invalid?");
106 assert(R2.isValid() && "Second range is invalid?");
107 if (R1.getEnd() != R2.getBegin() &&
108 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
109 return RangeBefore;
110 if (R2.getEnd() != R1.getBegin() &&
111 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
112 return RangeAfter;
113 return RangeOverlap;
114}
115
116/// \brief Determine if a source location falls within, before, or after a
117/// a given source range.
118static RangeComparisonResult LocationCompare(SourceManager &SM,
119 SourceLocation L, SourceRange R) {
120 assert(R.isValid() && "First range is invalid?");
121 assert(L.isValid() && "Second range is invalid?");
122 if (L == R.getBegin() || L == R.getEnd())
123 return RangeOverlap;
124 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
125 return RangeBefore;
126 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
127 return RangeAfter;
128 return RangeOverlap;
129}
130
131/// \brief Translate a Clang source range into a CIndex source range.
132///
133/// Clang internally represents ranges where the end location points to the
134/// start of the token at the end. However, for external clients it is more
135/// useful to have a CXSourceRange be a proper half-open interval. This routine
136/// does the appropriate translation.
137CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
138 const LangOptions &LangOpts,
139 const CharSourceRange &R) {
140 // We want the last character in this location, so we will adjust the
141 // location accordingly.
142 SourceLocation EndLoc = R.getEnd();
143 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
144 EndLoc = SM.getExpansionRange(EndLoc).second;
145 if (R.isTokenRange() && !EndLoc.isInvalid()) {
146 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
147 SM, LangOpts);
148 EndLoc = EndLoc.getLocWithOffset(Length);
149 }
150
Bill Wendlingeade3622013-01-23 08:25:41 +0000151 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000152 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 R.getBegin().getRawEncoding(),
154 EndLoc.getRawEncoding()
155 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000156 return Result;
157}
158
159//===----------------------------------------------------------------------===//
160// Cursor visitor.
161//===----------------------------------------------------------------------===//
162
163static SourceRange getRawCursorExtent(CXCursor C);
164static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
165
166
167RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
168 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
169}
170
171/// \brief Visit the given cursor and, if requested by the visitor,
172/// its children.
173///
174/// \param Cursor the cursor to visit.
175///
176/// \param CheckedRegionOfInterest if true, then the caller already checked
177/// that this cursor is within the region of interest.
178///
179/// \returns true if the visitation should be aborted, false if it
180/// should continue.
181bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
182 if (clang_isInvalid(Cursor.kind))
183 return false;
184
185 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000186 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000187 if (!D) {
188 assert(0 && "Invalid declaration cursor");
189 return true; // abort.
190 }
191
192 // Ignore implicit declarations, unless it's an objc method because
193 // currently we should report implicit methods for properties when indexing.
194 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
195 return false;
196 }
197
198 // If we have a range of interest, and this cursor doesn't intersect with it,
199 // we're done.
200 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
201 SourceRange Range = getRawCursorExtent(Cursor);
202 if (Range.isInvalid() || CompareRegionOfInterest(Range))
203 return false;
204 }
205
206 switch (Visitor(Cursor, Parent, ClientData)) {
207 case CXChildVisit_Break:
208 return true;
209
210 case CXChildVisit_Continue:
211 return false;
212
213 case CXChildVisit_Recurse: {
214 bool ret = VisitChildren(Cursor);
215 if (PostChildrenVisitor)
216 if (PostChildrenVisitor(Cursor, ClientData))
217 return true;
218 return ret;
219 }
220 }
221
222 llvm_unreachable("Invalid CXChildVisitResult!");
223}
224
225static bool visitPreprocessedEntitiesInRange(SourceRange R,
226 PreprocessingRecord &PPRec,
227 CursorVisitor &Visitor) {
228 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
229 FileID FID;
230
231 if (!Visitor.shouldVisitIncludedEntities()) {
232 // If the begin/end of the range lie in the same FileID, do the optimization
233 // where we skip preprocessed entities that do not come from the same FileID.
234 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
235 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
236 FID = FileID();
237 }
238
239 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
240 Entities = PPRec.getPreprocessedEntitiesInRange(R);
241 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
242 PPRec, FID);
243}
244
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000245bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000247 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000249 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 SourceManager &SM = Unit->getSourceManager();
251
252 std::pair<FileID, unsigned>
253 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
254 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
255
256 if (End.first != Begin.first) {
257 // If the end does not reside in the same file, try to recover by
258 // picking the end of the file of begin location.
259 End.first = Begin.first;
260 End.second = SM.getFileIDSize(Begin.first);
261 }
262
263 assert(Begin.first == End.first);
264 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000265 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000266
267 FileID File = Begin.first;
268 unsigned Offset = Begin.second;
269 unsigned Length = End.second - Begin.second;
270
271 if (!VisitDeclsOnly && !VisitPreprocessorLast)
272 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000274
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 if (visitDeclsFromFileRegion(File, Offset, Length))
276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
278 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return visitPreprocessedEntitiesInRegion();
280
281 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000282}
283
284static bool isInLexicalContext(Decl *D, DeclContext *DC) {
285 if (!DC)
286 return false;
287
288 for (DeclContext *DeclDC = D->getLexicalDeclContext();
289 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
290 if (DeclDC == DC)
291 return true;
292 }
293 return false;
294}
295
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000296bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000298 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 SourceManager &SM = Unit->getSourceManager();
300 SourceRange Range = RegionOfInterest;
301
302 SmallVector<Decl *, 16> Decls;
303 Unit->findFileRegionDecls(File, Offset, Length, Decls);
304
305 // If we didn't find any file level decls for the file, try looking at the
306 // file that it was included from.
307 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
308 bool Invalid = false;
309 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
310 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000311 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000312
313 SourceLocation Outer;
314 if (SLEntry.isFile())
315 Outer = SLEntry.getFile().getIncludeLoc();
316 else
317 Outer = SLEntry.getExpansion().getExpansionLocStart();
318 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000321 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000322 Length = 0;
323 Unit->findFileRegionDecls(File, Offset, Length, Decls);
324 }
325
326 assert(!Decls.empty());
327
328 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000329 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000330 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
331 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000332 Decl *D = *DIt;
333 if (D->getSourceRange().isInvalid())
334 continue;
335
336 if (isInLexicalContext(D, CurDC))
337 continue;
338
339 CurDC = dyn_cast<DeclContext>(D);
340
341 if (TagDecl *TD = dyn_cast<TagDecl>(D))
342 if (!TD->isFreeStanding())
343 continue;
344
345 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
346 if (CompRes == RangeBefore)
347 continue;
348 if (CompRes == RangeAfter)
349 break;
350
351 assert(CompRes == RangeOverlap);
352 VisitedAtLeastOnce = true;
353
354 if (isa<ObjCContainerDecl>(D)) {
355 FileDI_current = &DIt;
356 FileDE_current = DE;
357 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000358 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367
368 // No Decls overlapped with the range. Move up the lexical context until there
369 // is a context that contains the range or we reach the translation unit
370 // level.
371 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
372 : (*(DIt-1))->getLexicalDeclContext();
373
374 while (DC && !DC->isTranslationUnit()) {
375 Decl *D = cast<Decl>(DC);
376 SourceRange CurDeclRange = D->getSourceRange();
377 if (CurDeclRange.isInvalid())
378 break;
379
380 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
382 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000383 }
384
385 DC = D->getLexicalDeclContext();
386 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000387
388 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000389}
390
391bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
392 if (!AU->getPreprocessor().getPreprocessingRecord())
393 return false;
394
395 PreprocessingRecord &PPRec
396 = *AU->getPreprocessor().getPreprocessingRecord();
397 SourceManager &SM = AU->getSourceManager();
398
399 if (RegionOfInterest.isValid()) {
400 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
401 SourceLocation B = MappedRange.getBegin();
402 SourceLocation E = MappedRange.getEnd();
403
404 if (AU->isInPreambleFileID(B)) {
405 if (SM.isLoadedSourceLocation(E))
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
407 PPRec, *this);
408
409 // Beginning of range lies in the preamble but it also extends beyond
410 // it into the main file. Split the range into 2 parts, one covering
411 // the preamble and another covering the main file. This allows subsequent
412 // calls to visitPreprocessedEntitiesInRange to accept a source range that
413 // lies in the same FileID, allowing it to skip preprocessed entities that
414 // do not come from the same FileID.
415 bool breaked =
416 visitPreprocessedEntitiesInRange(
417 SourceRange(B, AU->getEndOfPreambleFileID()),
418 PPRec, *this);
419 if (breaked) return true;
420 return visitPreprocessedEntitiesInRange(
421 SourceRange(AU->getStartOfMainFileID(), E),
422 PPRec, *this);
423 }
424
425 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
426 }
427
428 bool OnlyLocalDecls
429 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
430
431 if (OnlyLocalDecls)
432 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
433 PPRec);
434
435 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
436}
437
438template<typename InputIterator>
439bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
440 InputIterator Last,
441 PreprocessingRecord &PPRec,
442 FileID FID) {
443 for (; First != Last; ++First) {
444 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
445 continue;
446
447 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000448 if (!PPE)
449 continue;
450
Guy Benyei11169dd2012-12-18 14:30:41 +0000451 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
452 if (Visit(MakeMacroExpansionCursor(ME, TU)))
453 return true;
454
455 continue;
456 }
457
458 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
459 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
460 return true;
461
462 continue;
463 }
464
465 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
466 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
467 return true;
468
469 continue;
470 }
471 }
472
473 return false;
474}
475
476/// \brief Visit the children of the given cursor.
477///
478/// \returns true if the visitation should be aborted, false if it
479/// should continue.
480bool CursorVisitor::VisitChildren(CXCursor Cursor) {
481 if (clang_isReference(Cursor.kind) &&
482 Cursor.kind != CXCursor_CXXBaseSpecifier) {
483 // By definition, references have no children.
484 return false;
485 }
486
487 // Set the Parent field to Cursor, then back to its old value once we're
488 // done.
489 SetParentRAII SetParent(Parent, StmtParent, Cursor);
490
491 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000492 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000493 if (!D)
494 return false;
495
496 return VisitAttributes(D) || Visit(D);
497 }
498
499 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000500 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000501 return Visit(S);
502
503 return false;
504 }
505
506 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000507 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000508 return Visit(E);
509
510 return false;
511 }
512
513 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000514 CXTranslationUnit TU = getCursorTU(Cursor);
515 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000516
517 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
518 for (unsigned I = 0; I != 2; ++I) {
519 if (VisitOrder[I]) {
520 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
521 RegionOfInterest.isInvalid()) {
522 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
523 TLEnd = CXXUnit->top_level_end();
524 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000525 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000526 return true;
527 }
528 } else if (VisitDeclContext(
529 CXXUnit->getASTContext().getTranslationUnitDecl()))
530 return true;
531 continue;
532 }
533
534 // Walk the preprocessing record.
535 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
536 visitPreprocessedEntitiesInRegion();
537 }
538
539 return false;
540 }
541
542 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000543 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
545 return Visit(BaseTSInfo->getTypeLoc());
546 }
547 }
548 }
549
550 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000551 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000553 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000554 return Visit(cxcursor::MakeCursorObjCClassRef(
555 ObjT->getInterface(),
556 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 }
558
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000559 // If pointing inside a macro definition, check if the token is an identifier
560 // that was ever defined as a macro. In such a case, create a "pseudo" macro
561 // expansion cursor for that token.
562 SourceLocation BeginLoc = RegionOfInterest.getBegin();
563 if (Cursor.kind == CXCursor_MacroDefinition &&
564 BeginLoc == RegionOfInterest.getEnd()) {
565 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000566 const MacroInfo *MI =
567 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000568 if (MacroDefinition *MacroDef =
569 checkForMacroInMacroDefinition(MI, Loc, TU))
570 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
571 }
572
Guy Benyei11169dd2012-12-18 14:30:41 +0000573 // Nothing to visit at the moment.
574 return false;
575}
576
577bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
578 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
579 if (Visit(TSInfo->getTypeLoc()))
580 return true;
581
582 if (Stmt *Body = B->getBody())
583 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
584
585 return false;
586}
587
Ted Kremenek03325582013-02-21 01:29:01 +0000588Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000589 if (RegionOfInterest.isValid()) {
590 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
591 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 switch (CompareRegionOfInterest(Range)) {
595 case RangeBefore:
596 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 case RangeAfter:
600 // This declaration comes after the region of interest; we're done.
601 return false;
602
603 case RangeOverlap:
604 // This declaration overlaps the region of interest; visit it.
605 break;
606 }
607 }
608 return true;
609}
610
611bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
612 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
613
614 // FIXME: Eventually remove. This part of a hack to support proper
615 // iteration over all Decls contained lexically within an ObjC container.
616 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
617 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
618
619 for ( ; I != E; ++I) {
620 Decl *D = *I;
621 if (D->getLexicalDeclContext() != DC)
622 continue;
623 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
624
625 // Ignore synthesized ivars here, otherwise if we have something like:
626 // @synthesize prop = _prop;
627 // and '_prop' is not declared, we will encounter a '_prop' ivar before
628 // encountering the 'prop' synthesize declaration and we will think that
629 // we passed the region-of-interest.
630 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
631 if (ivarD->getSynthesize())
632 continue;
633 }
634
635 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
636 // declarations is a mismatch with the compiler semantics.
637 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
638 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
639 if (!ID->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
641
642 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
643 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
644 if (!PD->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
646 }
647
Ted Kremenek03325582013-02-21 01:29:01 +0000648 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000649 if (!V.hasValue())
650 continue;
651 if (!V.getValue())
652 return false;
653 if (Visit(Cursor, true))
654 return true;
655 }
656 return false;
657}
658
659bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
660 llvm_unreachable("Translation units are visited directly by Visit()");
661}
662
663bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
664 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
665 return Visit(TSInfo->getTypeLoc());
666
667 return false;
668}
669
670bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
671 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
672 return Visit(TSInfo->getTypeLoc());
673
674 return false;
675}
676
677bool CursorVisitor::VisitTagDecl(TagDecl *D) {
678 return VisitDeclContext(D);
679}
680
681bool CursorVisitor::VisitClassTemplateSpecializationDecl(
682 ClassTemplateSpecializationDecl *D) {
683 bool ShouldVisitBody = false;
684 switch (D->getSpecializationKind()) {
685 case TSK_Undeclared:
686 case TSK_ImplicitInstantiation:
687 // Nothing to visit
688 return false;
689
690 case TSK_ExplicitInstantiationDeclaration:
691 case TSK_ExplicitInstantiationDefinition:
692 break;
693
694 case TSK_ExplicitSpecialization:
695 ShouldVisitBody = true;
696 break;
697 }
698
699 // Visit the template arguments used in the specialization.
700 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
701 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000702 if (TemplateSpecializationTypeLoc TSTLoc =
703 TL.getAs<TemplateSpecializationTypeLoc>()) {
704 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
705 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return true;
707 }
708 }
709
710 if (ShouldVisitBody && VisitCXXRecordDecl(D))
711 return true;
712
713 return false;
714}
715
716bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
717 ClassTemplatePartialSpecializationDecl *D) {
718 // FIXME: Visit the "outer" template parameter lists on the TagDecl
719 // before visiting these template parameters.
720 if (VisitTemplateParameters(D->getTemplateParameters()))
721 return true;
722
723 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000724 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
725 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
726 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000727 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
728 return true;
729
730 return VisitCXXRecordDecl(D);
731}
732
733bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
734 // Visit the default argument.
735 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
736 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
737 if (Visit(DefArg->getTypeLoc()))
738 return true;
739
740 return false;
741}
742
743bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
744 if (Expr *Init = D->getInitExpr())
745 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
746 return false;
747}
748
749bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000750 unsigned NumParamList = DD->getNumTemplateParameterLists();
751 for (unsigned i = 0; i < NumParamList; i++) {
752 TemplateParameterList* Params = DD->getTemplateParameterList(i);
753 if (VisitTemplateParameters(Params))
754 return true;
755 }
756
Guy Benyei11169dd2012-12-18 14:30:41 +0000757 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
758 if (Visit(TSInfo->getTypeLoc()))
759 return true;
760
761 // Visit the nested-name-specifier, if present.
762 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
763 if (VisitNestedNameSpecifierLoc(QualifierLoc))
764 return true;
765
766 return false;
767}
768
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000769/// \brief Compare two base or member initializers based on their source order.
770static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
771 CXXCtorInitializer *const *Y) {
772 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
773}
774
Guy Benyei11169dd2012-12-18 14:30:41 +0000775bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000776 unsigned NumParamList = ND->getNumTemplateParameterLists();
777 for (unsigned i = 0; i < NumParamList; i++) {
778 TemplateParameterList* Params = ND->getTemplateParameterList(i);
779 if (VisitTemplateParameters(Params))
780 return true;
781 }
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
784 // Visit the function declaration's syntactic components in the order
785 // written. This requires a bit of work.
786 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000787 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000788
789 // If we have a function declared directly (without the use of a typedef),
790 // visit just the return type. Otherwise, just visit the function's type
791 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000792 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000793 (!FTL && Visit(TL)))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000802 if (!isa<CXXDestructorDecl>(ND))
803 if (VisitDeclarationNameInfo(ND->getNameInfo()))
804 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000805
806 // FIXME: Visit explicitly-specified template arguments!
807
808 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000809 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000810 return true;
811
Bill Wendling44426052012-12-20 19:22:21 +0000812 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 }
814
815 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
816 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
817 // Find the initializers that were written in the source.
818 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 for (auto *I : Constructor->inits()) {
820 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 continue;
822
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000827 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
828 &CompareCXXCtorInitializers);
829
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 // Visit the initializers in source order
831 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
832 CXXCtorInitializer *Init = WrittenInits[I];
833 if (Init->isAnyMemberInitializer()) {
834 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
835 Init->getMemberLocation(), TU)))
836 return true;
837 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
838 if (Visit(TInfo->getTypeLoc()))
839 return true;
840 }
841
842 // Visit the initializer value.
843 if (Expr *Initializer = Init->getInit())
844 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
845 return true;
846 }
847 }
848
849 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
850 return true;
851 }
852
853 return false;
854}
855
856bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
857 if (VisitDeclaratorDecl(D))
858 return true;
859
860 if (Expr *BitWidth = D->getBitWidth())
861 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
862
863 return false;
864}
865
866bool CursorVisitor::VisitVarDecl(VarDecl *D) {
867 if (VisitDeclaratorDecl(D))
868 return true;
869
870 if (Expr *Init = D->getInit())
871 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
877 if (VisitDeclaratorDecl(D))
878 return true;
879
880 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
881 if (Expr *DefArg = D->getDefaultArgument())
882 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
888 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
889 // before visiting these template parameters.
890 if (VisitTemplateParameters(D->getTemplateParameters()))
891 return true;
892
893 return VisitFunctionDecl(D->getTemplatedDecl());
894}
895
896bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the TagDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitCXXRecordDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
906 if (VisitTemplateParameters(D->getTemplateParameters()))
907 return true;
908
909 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
910 VisitTemplateArgumentLoc(D->getDefaultArgument()))
911 return true;
912
913 return false;
914}
915
916bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000917 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 if (Visit(TSInfo->getTypeLoc()))
919 return true;
920
Aaron Ballman43b68be2014-03-07 17:50:17 +0000921 for (const auto *P : ND->params()) {
922 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 for (auto *SubDecl : D->decls()) {
986 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
987 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001665 for (const auto &I : D->bases()) {
1666 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001667 return true;
1668 }
1669 }
1670
1671 return VisitTagDecl(D);
1672}
1673
1674bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001675 for (const auto *I : D->attrs())
1676 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001711 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001787 case Stmt::OMPCriticalDirectiveClass:
1788 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001861 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001862 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001863 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001864 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001865 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001866 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001867 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001868 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001869 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001870 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001871 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001872 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001873 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001874 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001875 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876
Guy Benyei11169dd2012-12-18 14:30:41 +00001877private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1880 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1882 void AddStmt(const Stmt *S);
1883 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001886 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888} // end anonyous namespace
1889
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 // 'S' should always be non-null, since it comes from the
1892 // statement we are visiting.
1893 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1894}
1895
1896void
1897EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1898 if (Qualifier)
1899 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1900}
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (S)
1904 WL.push_back(StmtVisit(S, Parent));
1905}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (D)
1908 WL.push_back(DeclVisit(D, Parent, isFirst));
1909}
1910void EnqueueVisitor::
1911 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1912 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001914}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001915void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 if (D)
1917 WL.push_back(MemberRefVisit(D, L, Parent));
1918}
1919void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1920 if (TI)
1921 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1922 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 AddStmt(*Child);
1927 }
1928 if (size == WL.size())
1929 return;
1930 // Now reverse the entries we just added. This will match the DFS
1931 // ordering performed by the worklist.
1932 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1933 std::reverse(I, E);
1934}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935namespace {
1936class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1937 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001938 /// \brief Process clauses with list of variables.
1939 template <typename T>
1940 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941public:
1942 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1943#define OPENMP_CLAUSE(Name, Class) \
1944 void Visit##Class(const Class *C);
1945#include "clang/Basic/OpenMPKinds.def"
1946};
1947
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001948void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1949 Visitor->AddStmt(C->getCondition());
1950}
1951
Alexey Bataev3778b602014-07-17 07:32:53 +00001952void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev568a8332014-03-06 06:15:19 +00001956void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1957 Visitor->AddStmt(C->getNumThreads());
1958}
1959
Alexey Bataev62c87d22014-03-21 04:51:18 +00001960void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1961 Visitor->AddStmt(C->getSafelen());
1962}
1963
Alexander Musman8bd31e62014-05-27 15:12:19 +00001964void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1965 Visitor->AddStmt(C->getNumForLoops());
1966}
1967
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001969
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001970void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1971
Alexey Bataev56dafe82014-06-20 07:16:17 +00001972void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1973 Visitor->AddStmt(C->getChunkSize());
1974}
1975
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001976void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1977
Alexey Bataev236070f2014-06-20 11:19:47 +00001978void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1979
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001980void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1981
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001982void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1983
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001984void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1985
Alexey Bataevdea47612014-07-23 07:46:59 +00001986void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1987
Alexey Bataev67a4f222014-07-23 10:25:33 +00001988void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1989
Alexey Bataev459dec02014-07-24 06:46:57 +00001990void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1991
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001992void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1993
Alexey Bataev756c1962013-09-24 03:17:45 +00001994template<typename T>
1995void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001996 for (const auto *I : Node->varlists())
1997 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001998}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001999
2000void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002001 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002002}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002003void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2004 const OMPFirstprivateClause *C) {
2005 VisitOMPClauseList(C);
2006}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002007void OMPClauseEnqueue::VisitOMPLastprivateClause(
2008 const OMPLastprivateClause *C) {
2009 VisitOMPClauseList(C);
2010}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002011void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002012 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002013}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002014void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2015 VisitOMPClauseList(C);
2016}
Alexander Musman8dba6642014-04-22 13:09:42 +00002017void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2018 VisitOMPClauseList(C);
2019 Visitor->AddStmt(C->getStep());
2020}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002021void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2022 VisitOMPClauseList(C);
2023 Visitor->AddStmt(C->getAlignment());
2024}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002025void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2026 VisitOMPClauseList(C);
2027}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002028void
2029OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexey Bataev6125da92014-07-21 11:26:11 +00002032void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2033 VisitOMPClauseList(C);
2034}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002035}
Alexey Bataev756c1962013-09-24 03:17:45 +00002036
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002037void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2038 unsigned size = WL.size();
2039 OMPClauseEnqueue Visitor(this);
2040 Visitor.Visit(S);
2041 if (size == WL.size())
2042 return;
2043 // Now reverse the entries we just added. This will match the DFS
2044 // ordering performed by the worklist.
2045 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2046 std::reverse(I, E);
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2050}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 AddDecl(B->getBlockDecl());
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 AddTypeLoc(E->getTypeSourceInfo());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2059 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 E = S->body_rend(); I != E; ++I) {
2061 AddStmt(*I);
2062 }
2063}
2064void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 AddStmt(S->getSubStmt());
2067 AddDeclarationNameInfo(S);
2068 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2069 AddNestedNameSpecifierLoc(QualifierLoc);
2070}
2071
2072void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2075 AddDeclarationNameInfo(E);
2076 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2077 AddNestedNameSpecifierLoc(QualifierLoc);
2078 if (!E->isImplicitAccess())
2079 AddStmt(E->getBase());
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 // Enqueue the initializer , if any.
2083 AddStmt(E->getInitializer());
2084 // Enqueue the array size, if any.
2085 AddStmt(E->getArraySize());
2086 // Enqueue the allocated type.
2087 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2088 // Enqueue the placement arguments.
2089 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2090 AddStmt(E->getPlacementArg(I-1));
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2094 AddStmt(CE->getArg(I-1));
2095 AddStmt(CE->getCallee());
2096 AddStmt(CE->getArg(0));
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2099 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 // Visit the name of the type being destroyed.
2101 AddTypeLoc(E->getDestroyedTypeInfo());
2102 // Visit the scope type that looks disturbingly like the nested-name-specifier
2103 // but isn't.
2104 AddTypeLoc(E->getScopeTypeInfo());
2105 // Visit the nested-name-specifier.
2106 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2107 AddNestedNameSpecifierLoc(QualifierLoc);
2108 // Visit base expression.
2109 AddStmt(E->getBase());
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2112 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 AddTypeLoc(E->getTypeSourceInfo());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2116 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 EnqueueChildren(E);
2118 AddTypeLoc(E->getTypeSourceInfo());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 EnqueueChildren(E);
2122 if (E->isTypeOperand())
2123 AddTypeLoc(E->getTypeOperandSourceInfo());
2124}
2125
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2127 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 EnqueueChildren(E);
2129 AddTypeLoc(E->getTypeSourceInfo());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 if (E->isTypeOperand())
2134 AddTypeLoc(E->getTypeOperandSourceInfo());
2135}
2136
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(S);
2139 AddDecl(S->getExceptionDecl());
2140}
2141
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 if (DR->hasExplicitTemplateArgs()) {
2144 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2145 }
2146 WL.push_back(DeclRefExprParts(DR, Parent));
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2149 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2151 AddDeclarationNameInfo(E);
2152 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 unsigned size = WL.size();
2156 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002157 for (const auto *D : S->decls()) {
2158 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 isFirst = false;
2160 }
2161 if (size == WL.size())
2162 return;
2163 // Now reverse the entries we just added. This will match the DFS
2164 // ordering performed by the worklist.
2165 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2166 std::reverse(I, E);
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 D = E->designators_rbegin(), DEnd = E->designators_rend();
2172 D != DEnd; ++D) {
2173 if (D->isFieldDesignator()) {
2174 if (FieldDecl *Field = D->getField())
2175 AddMemberRef(Field, D->getFieldLoc());
2176 continue;
2177 }
2178 if (D->isArrayDesignator()) {
2179 AddStmt(E->getArrayIndex(*D));
2180 continue;
2181 }
2182 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2183 AddStmt(E->getArrayRangeEnd(*D));
2184 AddStmt(E->getArrayRangeStart(*D));
2185 }
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 EnqueueChildren(E);
2189 AddTypeLoc(E->getTypeInfoAsWritten());
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(FS->getBody());
2193 AddStmt(FS->getInc());
2194 AddStmt(FS->getCond());
2195 AddDecl(FS->getConditionVariable());
2196 AddStmt(FS->getInit());
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddStmt(If->getElse());
2203 AddStmt(If->getThen());
2204 AddStmt(If->getCond());
2205 AddDecl(If->getConditionVariable());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 // We care about the syntactic form of the initializer list, only.
2209 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2210 IE = Syntactic;
2211 EnqueueChildren(IE);
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 WL.push_back(MemberExprParts(M, Parent));
2215
2216 // If the base of the member access expression is an implicit 'this', don't
2217 // visit it.
2218 // FIXME: If we ever want to show these implicit accesses, this will be
2219 // unfortunate. However, clang_getCursor() relies on this behavior.
2220 if (!M->isImplicitAccess())
2221 AddStmt(M->getBase());
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 AddTypeLoc(E->getEncodedTypeSourceInfo());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 EnqueueChildren(M);
2228 AddTypeLoc(M->getClassReceiverTypeInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 // Visit the components of the offsetof expression.
2232 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2233 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2234 const OffsetOfNode &Node = E->getComponent(I-1);
2235 switch (Node.getKind()) {
2236 case OffsetOfNode::Array:
2237 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2238 break;
2239 case OffsetOfNode::Field:
2240 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2241 break;
2242 case OffsetOfNode::Identifier:
2243 case OffsetOfNode::Base:
2244 continue;
2245 }
2246 }
2247 // Visit the type into which we're computing the offset.
2248 AddTypeLoc(E->getTypeSourceInfo());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2252 WL.push_back(OverloadExprParts(E, Parent));
2253}
2254void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 EnqueueChildren(E);
2257 if (E->isArgumentType())
2258 AddTypeLoc(E->getArgumentTypeInfo());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(S);
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 AddStmt(S->getBody());
2265 AddStmt(S->getCond());
2266 AddDecl(S->getConditionVariable());
2267}
2268
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 AddStmt(W->getBody());
2271 AddStmt(W->getCond());
2272 AddDecl(W->getConditionVariable());
2273}
2274
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 for (unsigned I = E->getNumArgs(); I > 0; --I)
2277 AddTypeLoc(E->getArg(I-1));
2278}
2279
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 AddTypeLoc(E->getQueriedTypeSourceInfo());
2282}
2283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 EnqueueChildren(E);
2286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 VisitOverloadExpr(U);
2290 if (!U->isImplicitAccess())
2291 AddStmt(U->getBase());
2292}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 AddStmt(E->getSubExpr());
2295 AddTypeLoc(E->getWrittenTypeInfo());
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 WL.push_back(SizeOfPackExprParts(E, Parent));
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 // If the opaque value has a source expression, just transparently
2302 // visit that. This is useful for (e.g.) pseudo-object expressions.
2303 if (Expr *SourceExpr = E->getSourceExpr())
2304 return Visit(SourceExpr);
2305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 AddStmt(E->getBody());
2308 WL.push_back(LambdaExprParts(E, Parent));
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 // Treat the expression like its syntactic form.
2312 Visit(E->getSyntacticForm());
2313}
2314
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002315void EnqueueVisitor::VisitOMPExecutableDirective(
2316 const OMPExecutableDirective *D) {
2317 EnqueueChildren(D);
2318 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2319 E = D->clauses().end();
2320 I != E; ++I)
2321 EnqueueChildren(*I);
2322}
2323
2324void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2325 VisitOMPExecutableDirective(D);
2326}
2327
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002328void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataevf29276e2014-06-18 04:14:57 +00002332void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002336void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002340void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2341 VisitOMPExecutableDirective(D);
2342}
2343
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002344void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2345 VisitOMPExecutableDirective(D);
2346}
2347
Alexander Musman80c22892014-07-17 08:54:58 +00002348void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2349 VisitOMPExecutableDirective(D);
2350}
2351
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002352void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2353 VisitOMPExecutableDirective(D);
2354 AddDeclarationNameInfo(D);
2355}
2356
Alexey Bataev4acb8592014-07-07 13:01:15 +00002357void
2358EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2359 VisitOMPExecutableDirective(D);
2360}
2361
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002362void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2363 const OMPParallelSectionsDirective *D) {
2364 VisitOMPExecutableDirective(D);
2365}
2366
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002367void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369}
2370
Alexey Bataev68446b72014-07-18 07:47:19 +00002371void
2372EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2373 VisitOMPExecutableDirective(D);
2374}
2375
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002376void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2377 VisitOMPExecutableDirective(D);
2378}
2379
Alexey Bataev2df347a2014-07-18 10:17:07 +00002380void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2381 VisitOMPExecutableDirective(D);
2382}
2383
Alexey Bataev6125da92014-07-21 11:26:11 +00002384void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2385 VisitOMPExecutableDirective(D);
2386}
2387
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002388void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2389 VisitOMPExecutableDirective(D);
2390}
2391
Alexey Bataev0162e452014-07-22 10:10:35 +00002392void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2393 VisitOMPExecutableDirective(D);
2394}
2395
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2398}
2399
2400bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2401 if (RegionOfInterest.isValid()) {
2402 SourceRange Range = getRawCursorExtent(C);
2403 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2404 return false;
2405 }
2406 return true;
2407}
2408
2409bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2410 while (!WL.empty()) {
2411 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002412 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002413
2414 // Set the Parent field, then back to its old value once we're done.
2415 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2416
2417 switch (LI.getKind()) {
2418 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002419 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002420 if (!D)
2421 continue;
2422
2423 // For now, perform default visitation for Decls.
2424 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2425 cast<DeclVisit>(&LI)->isFirst())))
2426 return true;
2427
2428 continue;
2429 }
2430 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2431 const ASTTemplateArgumentListInfo *ArgList =
2432 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2433 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2434 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2435 Arg != ArgEnd; ++Arg) {
2436 if (VisitTemplateArgumentLoc(*Arg))
2437 return true;
2438 }
2439 continue;
2440 }
2441 case VisitorJob::TypeLocVisitKind: {
2442 // Perform default visitation for TypeLocs.
2443 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2444 return true;
2445 continue;
2446 }
2447 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002448 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 if (LabelStmt *stmt = LS->getStmt()) {
2450 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2451 TU))) {
2452 return true;
2453 }
2454 }
2455 continue;
2456 }
2457
2458 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2459 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2460 if (VisitNestedNameSpecifierLoc(V->get()))
2461 return true;
2462 continue;
2463 }
2464
2465 case VisitorJob::DeclarationNameInfoVisitKind: {
2466 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2467 ->get()))
2468 return true;
2469 continue;
2470 }
2471 case VisitorJob::MemberRefVisitKind: {
2472 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2473 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2474 return true;
2475 continue;
2476 }
2477 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002478 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 if (!S)
2480 continue;
2481
2482 // Update the current cursor.
2483 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2484 if (!IsInRegionOfInterest(Cursor))
2485 continue;
2486 switch (Visitor(Cursor, Parent, ClientData)) {
2487 case CXChildVisit_Break: return true;
2488 case CXChildVisit_Continue: break;
2489 case CXChildVisit_Recurse:
2490 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002491 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 EnqueueWorkList(WL, S);
2493 break;
2494 }
2495 continue;
2496 }
2497 case VisitorJob::MemberExprPartsKind: {
2498 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002499 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002500
2501 // Visit the nested-name-specifier
2502 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2503 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2504 return true;
2505
2506 // Visit the declaration name.
2507 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2508 return true;
2509
2510 // Visit the explicitly-specified template arguments, if any.
2511 if (M->hasExplicitTemplateArgs()) {
2512 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2513 *ArgEnd = Arg + M->getNumTemplateArgs();
2514 Arg != ArgEnd; ++Arg) {
2515 if (VisitTemplateArgumentLoc(*Arg))
2516 return true;
2517 }
2518 }
2519 continue;
2520 }
2521 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 // Visit nested-name-specifier, if present.
2524 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2525 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2526 return true;
2527 // Visit declaration name.
2528 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2529 return true;
2530 continue;
2531 }
2532 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002533 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 // Visit the nested-name-specifier.
2535 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2536 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2537 return true;
2538 // Visit the declaration name.
2539 if (VisitDeclarationNameInfo(O->getNameInfo()))
2540 return true;
2541 // Visit the overloaded declaration reference.
2542 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2543 return true;
2544 continue;
2545 }
2546 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002547 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 NamedDecl *Pack = E->getPack();
2549 if (isa<TemplateTypeParmDecl>(Pack)) {
2550 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2551 E->getPackLoc(), TU)))
2552 return true;
2553
2554 continue;
2555 }
2556
2557 if (isa<TemplateTemplateParmDecl>(Pack)) {
2558 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2559 E->getPackLoc(), TU)))
2560 return true;
2561
2562 continue;
2563 }
2564
2565 // Non-type template parameter packs and function parameter packs are
2566 // treated like DeclRefExpr cursors.
2567 continue;
2568 }
2569
2570 case VisitorJob::LambdaExprPartsKind: {
2571 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002572 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2574 CEnd = E->explicit_capture_end();
2575 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002576 // FIXME: Lambda init-captures.
2577 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002578 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002579
Guy Benyei11169dd2012-12-18 14:30:41 +00002580 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2581 C->getLocation(),
2582 TU)))
2583 return true;
2584 }
2585
2586 // Visit parameters and return type, if present.
2587 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2588 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2589 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2590 // Visit the whole type.
2591 if (Visit(TL))
2592 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002593 } else if (FunctionProtoTypeLoc Proto =
2594 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 if (E->hasExplicitParameters()) {
2596 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002597 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2598 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 return true;
2600 } else {
2601 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002602 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 return true;
2604 }
2605 }
2606 }
2607 break;
2608 }
2609
2610 case VisitorJob::PostChildrenVisitKind:
2611 if (PostChildrenVisitor(Parent, ClientData))
2612 return true;
2613 break;
2614 }
2615 }
2616 return false;
2617}
2618
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002619bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002620 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002621 if (!WorkListFreeList.empty()) {
2622 WL = WorkListFreeList.back();
2623 WL->clear();
2624 WorkListFreeList.pop_back();
2625 }
2626 else {
2627 WL = new VisitorWorkList();
2628 WorkListCache.push_back(WL);
2629 }
2630 EnqueueWorkList(*WL, S);
2631 bool result = RunVisitorWorkList(*WL);
2632 WorkListFreeList.push_back(WL);
2633 return result;
2634}
2635
2636namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002637typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002638RefNamePieces
2639buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2640 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2641 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2643 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2644 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2645
2646 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2647
2648 RefNamePieces Pieces;
2649
2650 if (WantQualifier && QLoc.isValid())
2651 Pieces.push_back(QLoc);
2652
2653 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2654 Pieces.push_back(NI.getLoc());
2655
2656 if (WantTemplateArgs && TemplateArgs)
2657 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2658 TemplateArgs->RAngleLoc));
2659
2660 if (Kind == DeclarationName::CXXOperatorName) {
2661 Pieces.push_back(SourceLocation::getFromRawEncoding(
2662 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2663 Pieces.push_back(SourceLocation::getFromRawEncoding(
2664 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2665 }
2666
2667 if (WantSinglePiece) {
2668 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2669 Pieces.clear();
2670 Pieces.push_back(R);
2671 }
2672
2673 return Pieces;
2674}
2675}
2676
2677//===----------------------------------------------------------------------===//
2678// Misc. API hooks.
2679//===----------------------------------------------------------------------===//
2680
Chad Rosier05c71aa2013-03-27 18:28:23 +00002681static void fatal_error_handler(void *user_data, const std::string& reason,
2682 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002683 // Write the result out to stderr avoiding errs() because raw_ostreams can
2684 // call report_fatal_error.
2685 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2686 ::abort();
2687}
2688
Chandler Carruth66660742014-06-27 16:37:27 +00002689namespace {
2690struct RegisterFatalErrorHandler {
2691 RegisterFatalErrorHandler() {
2692 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2693 }
2694};
2695}
2696
2697static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2698
Guy Benyei11169dd2012-12-18 14:30:41 +00002699extern "C" {
2700CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2701 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 // We use crash recovery to make some of our APIs more reliable, implicitly
2703 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002704 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2705 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002706
Chandler Carruth66660742014-06-27 16:37:27 +00002707 // Look through the managed static to trigger construction of the managed
2708 // static which registers our fatal error handler. This ensures it is only
2709 // registered once.
2710 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002711
2712 CIndexer *CIdxr = new CIndexer();
2713 if (excludeDeclarationsFromPCH)
2714 CIdxr->setOnlyLocalDecls();
2715 if (displayDiagnostics)
2716 CIdxr->setDisplayDiagnostics();
2717
2718 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2719 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2720 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2721 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2722 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2723 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2724
2725 return CIdxr;
2726}
2727
2728void clang_disposeIndex(CXIndex CIdx) {
2729 if (CIdx)
2730 delete static_cast<CIndexer *>(CIdx);
2731}
2732
2733void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2734 if (CIdx)
2735 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2736}
2737
2738unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2739 if (CIdx)
2740 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2741 return 0;
2742}
2743
2744void clang_toggleCrashRecovery(unsigned isEnabled) {
2745 if (isEnabled)
2746 llvm::CrashRecoveryContext::Enable();
2747 else
2748 llvm::CrashRecoveryContext::Disable();
2749}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002750
Guy Benyei11169dd2012-12-18 14:30:41 +00002751CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2752 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002753 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002754 enum CXErrorCode Result =
2755 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002756 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002757 assert((TU && Result == CXError_Success) ||
2758 (!TU && Result != CXError_Success));
2759 return TU;
2760}
2761
2762enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2763 const char *ast_filename,
2764 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002765 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002766 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002767
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002768 if (!CIdx || !ast_filename || !out_TU)
2769 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002770
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002771 LOG_FUNC_SECTION {
2772 *Log << ast_filename;
2773 }
2774
Guy Benyei11169dd2012-12-18 14:30:41 +00002775 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2776 FileSystemOptions FileSystemOpts;
2777
2778 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002779 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002780 CXXIdx->getOnlyLocalDecls(), None,
2781 /*CaptureDiagnostics=*/true,
2782 /*AllowPCHWithCompilerErrors=*/true,
2783 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002784 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2785 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002786}
2787
2788unsigned clang_defaultEditingTranslationUnitOptions() {
2789 return CXTranslationUnit_PrecompiledPreamble |
2790 CXTranslationUnit_CacheCompletionResults;
2791}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792
Guy Benyei11169dd2012-12-18 14:30:41 +00002793CXTranslationUnit
2794clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2795 const char *source_filename,
2796 int num_command_line_args,
2797 const char * const *command_line_args,
2798 unsigned num_unsaved_files,
2799 struct CXUnsavedFile *unsaved_files) {
2800 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2801 return clang_parseTranslationUnit(CIdx, source_filename,
2802 command_line_args, num_command_line_args,
2803 unsaved_files, num_unsaved_files,
2804 Options);
2805}
2806
2807struct ParseTranslationUnitInfo {
2808 CXIndex CIdx;
2809 const char *source_filename;
2810 const char *const *command_line_args;
2811 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002812 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002814 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002815 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002816};
2817static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002818 const ParseTranslationUnitInfo *PTUI =
2819 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002820 CXIndex CIdx = PTUI->CIdx;
2821 const char *source_filename = PTUI->source_filename;
2822 const char * const *command_line_args = PTUI->command_line_args;
2823 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002825 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002826
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002827 // Set up the initial return values.
2828 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002829 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002830
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002831 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002832 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 }
2836
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2838
2839 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2840 setThreadBackgroundPriority();
2841
2842 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2843 // FIXME: Add a flag for modules.
2844 TranslationUnitKind TUKind
2845 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002846 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 = options & CXTranslationUnit_CacheCompletionResults;
2848 bool IncludeBriefCommentsInCodeCompletion
2849 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2850 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2851 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2852
2853 // Configure the diagnostics.
2854 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002855 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002856
2857 // Recover resources if we crash before exiting this function.
2858 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2859 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002860 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002861
Ahmed Charlesb8984322014-03-07 20:03:18 +00002862 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2863 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002864
2865 // Recover resources if we crash before exiting this function.
2866 llvm::CrashRecoveryContextCleanupRegistrar<
2867 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2868
Alp Toker9d85b182014-07-07 01:23:14 +00002869 for (auto &UF : PTUI->unsaved_files) {
2870 llvm::MemoryBuffer *MB =
2871 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2872 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 }
2874
Ahmed Charlesb8984322014-03-07 20:03:18 +00002875 std::unique_ptr<std::vector<const char *>> Args(
2876 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002877
2878 // Recover resources if we crash before exiting this method.
2879 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2880 ArgsCleanup(Args.get());
2881
2882 // Since the Clang C library is primarily used by batch tools dealing with
2883 // (often very broken) source code, where spell-checking can have a
2884 // significant negative impact on performance (particularly when
2885 // precompiled headers are involved), we disable it by default.
2886 // Only do this if we haven't found a spell-checking-related argument.
2887 bool FoundSpellCheckingArgument = false;
2888 for (int I = 0; I != num_command_line_args; ++I) {
2889 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2890 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2891 FoundSpellCheckingArgument = true;
2892 break;
2893 }
2894 }
2895 if (!FoundSpellCheckingArgument)
2896 Args->push_back("-fno-spell-checking");
2897
2898 Args->insert(Args->end(), command_line_args,
2899 command_line_args + num_command_line_args);
2900
2901 // The 'source_filename' argument is optional. If the caller does not
2902 // specify it then it is assumed that the source file is specified
2903 // in the actual argument list.
2904 // Put the source file after command_line_args otherwise if '-x' flag is
2905 // present it will be unused.
2906 if (source_filename)
2907 Args->push_back(source_filename);
2908
2909 // Do we need the detailed preprocessing record?
2910 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2911 Args->push_back("-Xclang");
2912 Args->push_back("-detailed-preprocessing-record");
2913 }
2914
2915 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002916 std::unique_ptr<ASTUnit> ErrUnit;
2917 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002918 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002919 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2920 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2921 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2922 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2923 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2924 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
2926 if (NumErrors != Diags->getClient()->getNumErrors()) {
2927 // Make sure to check that 'Unit' is non-NULL.
2928 if (CXXIdx->getDisplayDiagnostics())
2929 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2930 }
2931
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002932 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2933 PTUI->result = CXError_ASTReadError;
2934 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002935 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002936 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2937 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002938}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002939
2940CXTranslationUnit
2941clang_parseTranslationUnit(CXIndex CIdx,
2942 const char *source_filename,
2943 const char *const *command_line_args,
2944 int num_command_line_args,
2945 struct CXUnsavedFile *unsaved_files,
2946 unsigned num_unsaved_files,
2947 unsigned options) {
2948 CXTranslationUnit TU;
2949 enum CXErrorCode Result = clang_parseTranslationUnit2(
2950 CIdx, source_filename, command_line_args, num_command_line_args,
2951 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002952 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002953 assert((TU && Result == CXError_Success) ||
2954 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002955 return TU;
2956}
2957
2958enum CXErrorCode clang_parseTranslationUnit2(
2959 CXIndex CIdx,
2960 const char *source_filename,
2961 const char *const *command_line_args,
2962 int num_command_line_args,
2963 struct CXUnsavedFile *unsaved_files,
2964 unsigned num_unsaved_files,
2965 unsigned options,
2966 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002967 LOG_FUNC_SECTION {
2968 *Log << source_filename << ": ";
2969 for (int i = 0; i != num_command_line_args; ++i)
2970 *Log << command_line_args[i] << " ";
2971 }
2972
Alp Toker9d85b182014-07-07 01:23:14 +00002973 if (num_unsaved_files && !unsaved_files)
2974 return CXError_InvalidArguments;
2975
Alp Toker5c532982014-07-07 22:42:03 +00002976 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002977 ParseTranslationUnitInfo PTUI = {
2978 CIdx,
2979 source_filename,
2980 command_line_args,
2981 num_command_line_args,
2982 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2983 options,
2984 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002985 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002986 llvm::CrashRecoveryContext CRC;
2987
2988 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2989 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2990 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2991 fprintf(stderr, " 'command_line_args' : [");
2992 for (int i = 0; i != num_command_line_args; ++i) {
2993 if (i)
2994 fprintf(stderr, ", ");
2995 fprintf(stderr, "'%s'", command_line_args[i]);
2996 }
2997 fprintf(stderr, "],\n");
2998 fprintf(stderr, " 'unsaved_files' : [");
2999 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3000 if (i)
3001 fprintf(stderr, ", ");
3002 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3003 unsaved_files[i].Length);
3004 }
3005 fprintf(stderr, "],\n");
3006 fprintf(stderr, " 'options' : %d,\n", options);
3007 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003008
3009 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 if (CXTranslationUnit *TU = PTUI.out_TU)
3012 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003013 }
Alp Toker5c532982014-07-07 22:42:03 +00003014
3015 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003016}
3017
3018unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3019 return CXSaveTranslationUnit_None;
3020}
3021
3022namespace {
3023
3024struct SaveTranslationUnitInfo {
3025 CXTranslationUnit TU;
3026 const char *FileName;
3027 unsigned options;
3028 CXSaveError result;
3029};
3030
3031}
3032
3033static void clang_saveTranslationUnit_Impl(void *UserData) {
3034 SaveTranslationUnitInfo *STUI =
3035 static_cast<SaveTranslationUnitInfo*>(UserData);
3036
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003037 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3039 setThreadBackgroundPriority();
3040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003041 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3043}
3044
3045int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3046 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003047 LOG_FUNC_SECTION {
3048 *Log << TU << ' ' << FileName;
3049 }
3050
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003051 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003052 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003054 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003055
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003056 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3058 if (!CXXUnit->hasSema())
3059 return CXSaveError_InvalidTU;
3060
3061 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3062
3063 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3064 getenv("LIBCLANG_NOTHREADS")) {
3065 clang_saveTranslationUnit_Impl(&STUI);
3066
3067 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3068 PrintLibclangResourceUsage(TU);
3069
3070 return STUI.result;
3071 }
3072
3073 // We have an AST that has invalid nodes due to compiler errors.
3074 // Use a crash recovery thread for protection.
3075
3076 llvm::CrashRecoveryContext CRC;
3077
3078 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3079 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3080 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3081 fprintf(stderr, " 'options' : %d,\n", options);
3082 fprintf(stderr, "}\n");
3083
3084 return CXSaveError_Unknown;
3085
3086 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3087 PrintLibclangResourceUsage(TU);
3088 }
3089
3090 return STUI.result;
3091}
3092
3093void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3094 if (CTUnit) {
3095 // If the translation unit has been marked as unsafe to free, just discard
3096 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003097 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3098 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003099 return;
3100
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003101 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003102 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3104 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003105 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 delete CTUnit;
3107 }
3108}
3109
3110unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3111 return CXReparse_None;
3112}
3113
3114struct ReparseTranslationUnitInfo {
3115 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003116 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003118 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003119};
3120
3121static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003122 const ReparseTranslationUnitInfo *RTUI =
3123 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003125 unsigned options = RTUI->options;
3126 (void) options;
3127
3128 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003129 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003130 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003131 RTUI->result = CXError_InvalidArguments;
3132 return;
3133 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003134
3135 // Reset the associated diagnostics.
3136 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003137 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003138
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003139 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3141 setThreadBackgroundPriority();
3142
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003143 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003145
3146 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3147 new std::vector<ASTUnit::RemappedFile>());
3148
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 // Recover resources if we crash before exiting this function.
3150 llvm::CrashRecoveryContextCleanupRegistrar<
3151 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003152
3153 for (auto &UF : RTUI->unsaved_files) {
3154 llvm::MemoryBuffer *MB =
3155 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3156 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003158
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003159 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003160 RTUI->result = CXError_Success;
3161 else if (isASTReadError(CXXUnit))
3162 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003163}
3164
3165int clang_reparseTranslationUnit(CXTranslationUnit TU,
3166 unsigned num_unsaved_files,
3167 struct CXUnsavedFile *unsaved_files,
3168 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003169 LOG_FUNC_SECTION {
3170 *Log << TU;
3171 }
3172
Alp Toker9d85b182014-07-07 01:23:14 +00003173 if (num_unsaved_files && !unsaved_files)
3174 return CXError_InvalidArguments;
3175
Alp Toker5c532982014-07-07 22:42:03 +00003176 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003177 ReparseTranslationUnitInfo RTUI = {
3178 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003179 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003180
3181 if (getenv("LIBCLANG_NOTHREADS")) {
3182 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003183 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 }
3185
3186 llvm::CrashRecoveryContext CRC;
3187
3188 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3189 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003190 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003191 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3193 PrintLibclangResourceUsage(TU);
3194
Alp Toker5c532982014-07-07 22:42:03 +00003195 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003196}
3197
3198
3199CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003200 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003201 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003202 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003203 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003204
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003205 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003206 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003207}
3208
3209CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003210 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003211 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003212 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003213 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3217}
3218
3219} // end: extern "C"
3220
3221//===----------------------------------------------------------------------===//
3222// CXFile Operations.
3223//===----------------------------------------------------------------------===//
3224
3225extern "C" {
3226CXString clang_getFileName(CXFile SFile) {
3227 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003228 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003229
3230 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003231 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003232}
3233
3234time_t clang_getFileTime(CXFile SFile) {
3235 if (!SFile)
3236 return 0;
3237
3238 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3239 return FEnt->getModificationTime();
3240}
3241
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003242CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003243 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003245 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003246 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003248 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003249
3250 FileManager &FMgr = CXXUnit->getFileManager();
3251 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3252}
3253
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003254unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3255 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003256 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003257 LOG_BAD_TU(TU);
3258 return 0;
3259 }
3260
3261 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return 0;
3263
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003264 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 FileEntry *FEnt = static_cast<FileEntry *>(file);
3266 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3267 .isFileMultipleIncludeGuarded(FEnt);
3268}
3269
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003270int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3271 if (!file || !outID)
3272 return 1;
3273
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003274 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003275 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3276 outID->data[0] = ID.getDevice();
3277 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003278 outID->data[2] = FEnt->getModificationTime();
3279 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003280}
3281
Guy Benyei11169dd2012-12-18 14:30:41 +00003282} // end: extern "C"
3283
3284//===----------------------------------------------------------------------===//
3285// CXCursor Operations.
3286//===----------------------------------------------------------------------===//
3287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288static const Decl *getDeclFromExpr(const Stmt *E) {
3289 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 return getDeclFromExpr(CE->getSubExpr());
3291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 if (PRE->isExplicitProperty())
3300 return PRE->getExplicitProperty();
3301 // It could be messaging both getter and setter as in:
3302 // ++myobj.myprop;
3303 // in which case prefer to associate the setter since it is less obvious
3304 // from inspecting the source that the setter is going to get called.
3305 if (PRE->isMessagingSetter())
3306 return PRE->getImplicitPropertySetter();
3307 return PRE->getImplicitPropertyGetter();
3308 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003309 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003311 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 if (Expr *Src = OVE->getSourceExpr())
3313 return getDeclFromExpr(Src);
3314
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 if (!CE->isElidable())
3319 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return OME->getMethodDecl();
3322
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003323 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3327 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003328 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3330 isa<ParmVarDecl>(SizeOfPack->getPack()))
3331 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003332
3333 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334}
3335
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003336static SourceLocation getLocationFromExpr(const Expr *E) {
3337 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 return getLocationFromExpr(CE->getSubExpr());
3339
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003340 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003342 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003344 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003346 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003348 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003350 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 return PropRef->getLocation();
3352
3353 return E->getLocStart();
3354}
3355
3356extern "C" {
3357
3358unsigned clang_visitChildren(CXCursor parent,
3359 CXCursorVisitor visitor,
3360 CXClientData client_data) {
3361 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3362 /*VisitPreprocessorLast=*/false);
3363 return CursorVis.VisitChildren(parent);
3364}
3365
3366#ifndef __has_feature
3367#define __has_feature(x) 0
3368#endif
3369#if __has_feature(blocks)
3370typedef enum CXChildVisitResult
3371 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3372
3373static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3374 CXClientData client_data) {
3375 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3376 return block(cursor, parent);
3377}
3378#else
3379// If we are compiled with a compiler that doesn't have native blocks support,
3380// define and call the block manually, so the
3381typedef struct _CXChildVisitResult
3382{
3383 void *isa;
3384 int flags;
3385 int reserved;
3386 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3387 CXCursor);
3388} *CXCursorVisitorBlock;
3389
3390static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3391 CXClientData client_data) {
3392 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3393 return block->invoke(block, cursor, parent);
3394}
3395#endif
3396
3397
3398unsigned clang_visitChildrenWithBlock(CXCursor parent,
3399 CXCursorVisitorBlock block) {
3400 return clang_visitChildren(parent, visitWithBlock, block);
3401}
3402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003403static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003405 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003409 if (const ObjCPropertyImplDecl *PropImpl =
3410 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003412 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003413
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003414 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003416 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003418 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 }
3420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003421 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003422 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3426 // and returns different names. NamedDecl returns the class name and
3427 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
3430 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003431 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003432
3433 SmallString<1024> S;
3434 llvm::raw_svector_ostream os(S);
3435 ND->printName(os);
3436
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438}
3439
3440CXString clang_getCursorSpelling(CXCursor C) {
3441 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003442 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
3444 if (clang_isReference(C.kind)) {
3445 switch (C.kind) {
3446 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003447 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003448 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 }
3450 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003451 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003452 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003455 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003457 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 }
3459 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003460 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 }
3463 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003464 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 assert(Type && "Missing type decl");
3466
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 getAsString());
3469 }
3470 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003471 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 assert(Template && "Missing template decl");
3473
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003474 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 }
3476
3477 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003478 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 assert(NS && "Missing namespace decl");
3480
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003481 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 }
3483
3484 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003485 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 assert(Field && "Missing member decl");
3487
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003488 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 }
3490
3491 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003492 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 assert(Label && "Missing label");
3494
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003495 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 }
3497
3498 case CXCursor_OverloadedDeclRef: {
3499 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3501 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003502 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003503 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003506 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 OverloadedTemplateStorage *Ovl
3508 = Storage.get<OverloadedTemplateStorage*>();
3509 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003510 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003511 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 }
3513
3514 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 assert(Var && "Missing variable decl");
3517
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003522 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 }
3524 }
3525
3526 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003527 const Expr *E = getCursorExpr(C);
3528
3529 if (C.kind == CXCursor_ObjCStringLiteral ||
3530 C.kind == CXCursor_StringLiteral) {
3531 const StringLiteral *SLit;
3532 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3533 SLit = OSL->getString();
3534 } else {
3535 SLit = cast<StringLiteral>(E);
3536 }
3537 SmallString<256> Buf;
3538 llvm::raw_svector_ostream OS(Buf);
3539 SLit->outputString(OS);
3540 return cxstring::createDup(OS.str());
3541 }
3542
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 if (D)
3545 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003546 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 }
3548
3549 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003550 const Stmt *S = getCursorStmt(C);
3551 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003553
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003554 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 }
3556
3557 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 ->getNameStart());
3560
3561 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 ->getNameStart());
3564
3565 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567
3568 if (clang_isDeclaration(C.kind))
3569 return getDeclSpelling(getCursorDecl(C));
3570
3571 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003572 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003573 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 }
3575
3576 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003577 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003578 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 }
3580
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003581 if (C.kind == CXCursor_PackedAttr) {
3582 return cxstring::createRef("packed");
3583 }
3584
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003585 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003586}
3587
3588CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3589 unsigned pieceIndex,
3590 unsigned options) {
3591 if (clang_Cursor_isNull(C))
3592 return clang_getNullRange();
3593
3594 ASTContext &Ctx = getCursorContext(C);
3595
3596 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003597 const Stmt *S = getCursorStmt(C);
3598 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (pieceIndex > 0)
3600 return clang_getNullRange();
3601 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3602 }
3603
3604 return clang_getNullRange();
3605 }
3606
3607 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003608 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3610 if (pieceIndex >= ME->getNumSelectorLocs())
3611 return clang_getNullRange();
3612 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3613 }
3614 }
3615
3616 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3617 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003618 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3620 if (pieceIndex >= MD->getNumSelectorLocs())
3621 return clang_getNullRange();
3622 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3623 }
3624 }
3625
3626 if (C.kind == CXCursor_ObjCCategoryDecl ||
3627 C.kind == CXCursor_ObjCCategoryImplDecl) {
3628 if (pieceIndex > 0)
3629 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003630 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3632 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003633 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3635 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3636 }
3637
3638 if (C.kind == CXCursor_ModuleImportDecl) {
3639 if (pieceIndex > 0)
3640 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003641 if (const ImportDecl *ImportD =
3642 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3644 if (!Locs.empty())
3645 return cxloc::translateSourceRange(Ctx,
3646 SourceRange(Locs.front(), Locs.back()));
3647 }
3648 return clang_getNullRange();
3649 }
3650
3651 // FIXME: A CXCursor_InclusionDirective should give the location of the
3652 // filename, but we don't keep track of this.
3653
3654 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3655 // but we don't keep track of this.
3656
3657 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3658 // but we don't keep track of this.
3659
3660 // Default handling, give the location of the cursor.
3661
3662 if (pieceIndex > 0)
3663 return clang_getNullRange();
3664
3665 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3666 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3667 return cxloc::translateSourceRange(Ctx, Loc);
3668}
3669
3670CXString clang_getCursorDisplayName(CXCursor C) {
3671 if (!clang_isDeclaration(C.kind))
3672 return clang_getCursorSpelling(C);
3673
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003676 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003677
3678 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 D = FunTmpl->getTemplatedDecl();
3681
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003682 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 SmallString<64> Str;
3684 llvm::raw_svector_ostream OS(Str);
3685 OS << *Function;
3686 if (Function->getPrimaryTemplate())
3687 OS << "<>";
3688 OS << "(";
3689 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3690 if (I)
3691 OS << ", ";
3692 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3693 }
3694
3695 if (Function->isVariadic()) {
3696 if (Function->getNumParams())
3697 OS << ", ";
3698 OS << "...";
3699 }
3700 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003701 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 }
3703
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003704 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 SmallString<64> Str;
3706 llvm::raw_svector_ostream OS(Str);
3707 OS << *ClassTemplate;
3708 OS << "<";
3709 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3710 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3711 if (I)
3712 OS << ", ";
3713
3714 NamedDecl *Param = Params->getParam(I);
3715 if (Param->getIdentifier()) {
3716 OS << Param->getIdentifier()->getName();
3717 continue;
3718 }
3719
3720 // There is no parameter name, which makes this tricky. Try to come up
3721 // with something useful that isn't too long.
3722 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3723 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3724 else if (NonTypeTemplateParmDecl *NTTP
3725 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3726 OS << NTTP->getType().getAsString(Policy);
3727 else
3728 OS << "template<...> class";
3729 }
3730
3731 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003732 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 }
3734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003735 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3737 // If the type was explicitly written, use that.
3738 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003739 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003740
Benjamin Kramer9170e912013-02-22 15:46:01 +00003741 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 llvm::raw_svector_ostream OS(Str);
3743 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003744 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 ClassSpec->getTemplateArgs().data(),
3746 ClassSpec->getTemplateArgs().size(),
3747 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003748 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 }
3750
3751 return clang_getCursorSpelling(C);
3752}
3753
3754CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3755 switch (Kind) {
3756 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003884 case CXCursor_ObjCSelfExpr:
3885 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00003974 case CXCursor_SEHLeaveStmt:
3975 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004004 case CXCursor_PackedAttr:
4005 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004006 case CXCursor_PureAttr:
4007 return cxstring::createRef("attribute(pure)");
4008 case CXCursor_ConstAttr:
4009 return cxstring::createRef("attribute(const)");
4010 case CXCursor_NoDuplicateAttr:
4011 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004012 case CXCursor_CUDAConstantAttr:
4013 return cxstring::createRef("attribute(constant)");
4014 case CXCursor_CUDADeviceAttr:
4015 return cxstring::createRef("attribute(device)");
4016 case CXCursor_CUDAGlobalAttr:
4017 return cxstring::createRef("attribute(global)");
4018 case CXCursor_CUDAHostAttr:
4019 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004068 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004069 return cxstring::createRef("OMPParallelDirective");
4070 case CXCursor_OMPSimdDirective:
4071 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004072 case CXCursor_OMPForDirective:
4073 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004074 case CXCursor_OMPSectionsDirective:
4075 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004076 case CXCursor_OMPSectionDirective:
4077 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004078 case CXCursor_OMPSingleDirective:
4079 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004080 case CXCursor_OMPMasterDirective:
4081 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004082 case CXCursor_OMPCriticalDirective:
4083 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004084 case CXCursor_OMPParallelForDirective:
4085 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004086 case CXCursor_OMPParallelSectionsDirective:
4087 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004088 case CXCursor_OMPTaskDirective:
4089 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004090 case CXCursor_OMPTaskyieldDirective:
4091 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004092 case CXCursor_OMPBarrierDirective:
4093 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004094 case CXCursor_OMPTaskwaitDirective:
4095 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004096 case CXCursor_OMPFlushDirective:
4097 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004098 case CXCursor_OMPOrderedDirective:
4099 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004100 case CXCursor_OMPAtomicDirective:
4101 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 }
4103
4104 llvm_unreachable("Unhandled CXCursorKind");
4105}
4106
4107struct GetCursorData {
4108 SourceLocation TokenBeginLoc;
4109 bool PointsAtMacroArgExpansion;
4110 bool VisitedObjCPropertyImplDecl;
4111 SourceLocation VisitedDeclaratorDeclStartLoc;
4112 CXCursor &BestCursor;
4113
4114 GetCursorData(SourceManager &SM,
4115 SourceLocation tokenBegin, CXCursor &outputCursor)
4116 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4117 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4118 VisitedObjCPropertyImplDecl = false;
4119 }
4120};
4121
4122static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4123 CXCursor parent,
4124 CXClientData client_data) {
4125 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4126 CXCursor *BestCursor = &Data->BestCursor;
4127
4128 // If we point inside a macro argument we should provide info of what the
4129 // token is so use the actual cursor, don't replace it with a macro expansion
4130 // cursor.
4131 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4132 return CXChildVisit_Recurse;
4133
4134 if (clang_isDeclaration(cursor.kind)) {
4135 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004136 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4138 if (MD->isImplicit())
4139 return CXChildVisit_Break;
4140
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004141 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4143 // Check that when we have multiple @class references in the same line,
4144 // that later ones do not override the previous ones.
4145 // If we have:
4146 // @class Foo, Bar;
4147 // source ranges for both start at '@', so 'Bar' will end up overriding
4148 // 'Foo' even though the cursor location was at 'Foo'.
4149 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4150 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004151 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4153 if (PrevID != ID &&
4154 !PrevID->isThisDeclarationADefinition() &&
4155 !ID->isThisDeclarationADefinition())
4156 return CXChildVisit_Break;
4157 }
4158
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004159 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4161 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4162 // Check that when we have multiple declarators in the same line,
4163 // that later ones do not override the previous ones.
4164 // If we have:
4165 // int Foo, Bar;
4166 // source ranges for both start at 'int', so 'Bar' will end up overriding
4167 // 'Foo' even though the cursor location was at 'Foo'.
4168 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4169 return CXChildVisit_Break;
4170 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004172 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4174 (void)PropImp;
4175 // Check that when we have multiple @synthesize in the same line,
4176 // that later ones do not override the previous ones.
4177 // If we have:
4178 // @synthesize Foo, Bar;
4179 // source ranges for both start at '@', so 'Bar' will end up overriding
4180 // 'Foo' even though the cursor location was at 'Foo'.
4181 if (Data->VisitedObjCPropertyImplDecl)
4182 return CXChildVisit_Break;
4183 Data->VisitedObjCPropertyImplDecl = true;
4184 }
4185 }
4186
4187 if (clang_isExpression(cursor.kind) &&
4188 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004189 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 // Avoid having the cursor of an expression replace the declaration cursor
4191 // when the expression source range overlaps the declaration range.
4192 // This can happen for C++ constructor expressions whose range generally
4193 // include the variable declaration, e.g.:
4194 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4195 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4196 D->getLocation() == Data->TokenBeginLoc)
4197 return CXChildVisit_Break;
4198 }
4199 }
4200
4201 // If our current best cursor is the construction of a temporary object,
4202 // don't replace that cursor with a type reference, because we want
4203 // clang_getCursor() to point at the constructor.
4204 if (clang_isExpression(BestCursor->kind) &&
4205 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4206 cursor.kind == CXCursor_TypeRef) {
4207 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4208 // as having the actual point on the type reference.
4209 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4210 return CXChildVisit_Recurse;
4211 }
4212
4213 *BestCursor = cursor;
4214 return CXChildVisit_Recurse;
4215}
4216
4217CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004218 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004219 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004221 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004222
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004223 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4225
4226 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4227 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4228
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004229 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 CXFile SearchFile;
4231 unsigned SearchLine, SearchColumn;
4232 CXFile ResultFile;
4233 unsigned ResultLine, ResultColumn;
4234 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4235 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4236 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004237
4238 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4239 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004240 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004241 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 SearchFileName = clang_getFileName(SearchFile);
4243 ResultFileName = clang_getFileName(ResultFile);
4244 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4245 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004246 *Log << llvm::format("(%s:%d:%d) = %s",
4247 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4248 clang_getCString(KindSpelling))
4249 << llvm::format("(%s:%d:%d):%s%s",
4250 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4251 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 clang_disposeString(SearchFileName);
4253 clang_disposeString(ResultFileName);
4254 clang_disposeString(KindSpelling);
4255 clang_disposeString(USR);
4256
4257 CXCursor Definition = clang_getCursorDefinition(Result);
4258 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4259 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4260 CXString DefinitionKindSpelling
4261 = clang_getCursorKindSpelling(Definition.kind);
4262 CXFile DefinitionFile;
4263 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004264 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004265 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004267 *Log << llvm::format(" -> %s(%s:%d:%d)",
4268 clang_getCString(DefinitionKindSpelling),
4269 clang_getCString(DefinitionFileName),
4270 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 clang_disposeString(DefinitionFileName);
4272 clang_disposeString(DefinitionKindSpelling);
4273 }
4274 }
4275
4276 return Result;
4277}
4278
4279CXCursor clang_getNullCursor(void) {
4280 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4281}
4282
4283unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004284 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4285 // can't set consistently. For example, when visiting a DeclStmt we will set
4286 // it but we don't set it on the result of clang_getCursorDefinition for
4287 // a reference of the same declaration.
4288 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4289 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4290 // to provide that kind of info.
4291 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004292 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004293 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004294 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004295
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 return X == Y;
4297}
4298
4299unsigned clang_hashCursor(CXCursor C) {
4300 unsigned Index = 0;
4301 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4302 Index = 1;
4303
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004304 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 std::make_pair(C.kind, C.data[Index]));
4306}
4307
4308unsigned clang_isInvalid(enum CXCursorKind K) {
4309 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4310}
4311
4312unsigned clang_isDeclaration(enum CXCursorKind K) {
4313 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4314 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4315}
4316
4317unsigned clang_isReference(enum CXCursorKind K) {
4318 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4319}
4320
4321unsigned clang_isExpression(enum CXCursorKind K) {
4322 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4323}
4324
4325unsigned clang_isStatement(enum CXCursorKind K) {
4326 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4327}
4328
4329unsigned clang_isAttribute(enum CXCursorKind K) {
4330 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4331}
4332
4333unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4334 return K == CXCursor_TranslationUnit;
4335}
4336
4337unsigned clang_isPreprocessing(enum CXCursorKind K) {
4338 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4339}
4340
4341unsigned clang_isUnexposed(enum CXCursorKind K) {
4342 switch (K) {
4343 case CXCursor_UnexposedDecl:
4344 case CXCursor_UnexposedExpr:
4345 case CXCursor_UnexposedStmt:
4346 case CXCursor_UnexposedAttr:
4347 return true;
4348 default:
4349 return false;
4350 }
4351}
4352
4353CXCursorKind clang_getCursorKind(CXCursor C) {
4354 return C.kind;
4355}
4356
4357CXSourceLocation clang_getCursorLocation(CXCursor C) {
4358 if (clang_isReference(C.kind)) {
4359 switch (C.kind) {
4360 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004361 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 = getCursorObjCSuperClassRef(C);
4363 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4364 }
4365
4366 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004367 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 = getCursorObjCProtocolRef(C);
4369 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4370 }
4371
4372 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004373 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 = getCursorObjCClassRef(C);
4375 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4376 }
4377
4378 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004379 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4381 }
4382
4383 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004384 std::pair<const TemplateDecl *, SourceLocation> P =
4385 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4387 }
4388
4389 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004390 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4392 }
4393
4394 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004395 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4397 }
4398
4399 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004400 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4402 }
4403
4404 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004405 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 if (!BaseSpec)
4407 return clang_getNullLocation();
4408
4409 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4410 return cxloc::translateSourceLocation(getCursorContext(C),
4411 TSInfo->getTypeLoc().getBeginLoc());
4412
4413 return cxloc::translateSourceLocation(getCursorContext(C),
4414 BaseSpec->getLocStart());
4415 }
4416
4417 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004418 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4420 }
4421
4422 case CXCursor_OverloadedDeclRef:
4423 return cxloc::translateSourceLocation(getCursorContext(C),
4424 getCursorOverloadedDeclRef(C).second);
4425
4426 default:
4427 // FIXME: Need a way to enumerate all non-reference cases.
4428 llvm_unreachable("Missed a reference kind");
4429 }
4430 }
4431
4432 if (clang_isExpression(C.kind))
4433 return cxloc::translateSourceLocation(getCursorContext(C),
4434 getLocationFromExpr(getCursorExpr(C)));
4435
4436 if (clang_isStatement(C.kind))
4437 return cxloc::translateSourceLocation(getCursorContext(C),
4438 getCursorStmt(C)->getLocStart());
4439
4440 if (C.kind == CXCursor_PreprocessingDirective) {
4441 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4442 return cxloc::translateSourceLocation(getCursorContext(C), L);
4443 }
4444
4445 if (C.kind == CXCursor_MacroExpansion) {
4446 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004447 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 return cxloc::translateSourceLocation(getCursorContext(C), L);
4449 }
4450
4451 if (C.kind == CXCursor_MacroDefinition) {
4452 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4453 return cxloc::translateSourceLocation(getCursorContext(C), L);
4454 }
4455
4456 if (C.kind == CXCursor_InclusionDirective) {
4457 SourceLocation L
4458 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4459 return cxloc::translateSourceLocation(getCursorContext(C), L);
4460 }
4461
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004462 if (clang_isAttribute(C.kind)) {
4463 SourceLocation L
4464 = cxcursor::getCursorAttr(C)->getLocation();
4465 return cxloc::translateSourceLocation(getCursorContext(C), L);
4466 }
4467
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 if (!clang_isDeclaration(C.kind))
4469 return clang_getNullLocation();
4470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004471 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 if (!D)
4473 return clang_getNullLocation();
4474
4475 SourceLocation Loc = D->getLocation();
4476 // FIXME: Multiple variables declared in a single declaration
4477 // currently lack the information needed to correctly determine their
4478 // ranges when accounting for the type-specifier. We use context
4479 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4480 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004481 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 if (!cxcursor::isFirstInDeclGroup(C))
4483 Loc = VD->getLocation();
4484 }
4485
4486 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004487 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 Loc = MD->getSelectorStartLoc();
4489
4490 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4491}
4492
4493} // end extern "C"
4494
4495CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4496 assert(TU);
4497
4498 // Guard against an invalid SourceLocation, or we may assert in one
4499 // of the following calls.
4500 if (SLoc.isInvalid())
4501 return clang_getNullCursor();
4502
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004503 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004504
4505 // Translate the given source location to make it point at the beginning of
4506 // the token under the cursor.
4507 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4508 CXXUnit->getASTContext().getLangOpts());
4509
4510 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4511 if (SLoc.isValid()) {
4512 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4513 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4514 /*VisitPreprocessorLast=*/true,
4515 /*VisitIncludedEntities=*/false,
4516 SourceLocation(SLoc));
4517 CursorVis.visitFileRegion();
4518 }
4519
4520 return Result;
4521}
4522
4523static SourceRange getRawCursorExtent(CXCursor C) {
4524 if (clang_isReference(C.kind)) {
4525 switch (C.kind) {
4526 case CXCursor_ObjCSuperClassRef:
4527 return getCursorObjCSuperClassRef(C).second;
4528
4529 case CXCursor_ObjCProtocolRef:
4530 return getCursorObjCProtocolRef(C).second;
4531
4532 case CXCursor_ObjCClassRef:
4533 return getCursorObjCClassRef(C).second;
4534
4535 case CXCursor_TypeRef:
4536 return getCursorTypeRef(C).second;
4537
4538 case CXCursor_TemplateRef:
4539 return getCursorTemplateRef(C).second;
4540
4541 case CXCursor_NamespaceRef:
4542 return getCursorNamespaceRef(C).second;
4543
4544 case CXCursor_MemberRef:
4545 return getCursorMemberRef(C).second;
4546
4547 case CXCursor_CXXBaseSpecifier:
4548 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4549
4550 case CXCursor_LabelRef:
4551 return getCursorLabelRef(C).second;
4552
4553 case CXCursor_OverloadedDeclRef:
4554 return getCursorOverloadedDeclRef(C).second;
4555
4556 case CXCursor_VariableRef:
4557 return getCursorVariableRef(C).second;
4558
4559 default:
4560 // FIXME: Need a way to enumerate all non-reference cases.
4561 llvm_unreachable("Missed a reference kind");
4562 }
4563 }
4564
4565 if (clang_isExpression(C.kind))
4566 return getCursorExpr(C)->getSourceRange();
4567
4568 if (clang_isStatement(C.kind))
4569 return getCursorStmt(C)->getSourceRange();
4570
4571 if (clang_isAttribute(C.kind))
4572 return getCursorAttr(C)->getRange();
4573
4574 if (C.kind == CXCursor_PreprocessingDirective)
4575 return cxcursor::getCursorPreprocessingDirective(C);
4576
4577 if (C.kind == CXCursor_MacroExpansion) {
4578 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004579 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 return TU->mapRangeFromPreamble(Range);
4581 }
4582
4583 if (C.kind == CXCursor_MacroDefinition) {
4584 ASTUnit *TU = getCursorASTUnit(C);
4585 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4586 return TU->mapRangeFromPreamble(Range);
4587 }
4588
4589 if (C.kind == CXCursor_InclusionDirective) {
4590 ASTUnit *TU = getCursorASTUnit(C);
4591 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4592 return TU->mapRangeFromPreamble(Range);
4593 }
4594
4595 if (C.kind == CXCursor_TranslationUnit) {
4596 ASTUnit *TU = getCursorASTUnit(C);
4597 FileID MainID = TU->getSourceManager().getMainFileID();
4598 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4599 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4600 return SourceRange(Start, End);
4601 }
4602
4603 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004604 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 if (!D)
4606 return SourceRange();
4607
4608 SourceRange R = D->getSourceRange();
4609 // FIXME: Multiple variables declared in a single declaration
4610 // currently lack the information needed to correctly determine their
4611 // ranges when accounting for the type-specifier. We use context
4612 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4613 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004614 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 if (!cxcursor::isFirstInDeclGroup(C))
4616 R.setBegin(VD->getLocation());
4617 }
4618 return R;
4619 }
4620 return SourceRange();
4621}
4622
4623/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4624/// the decl-specifier-seq for declarations.
4625static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4626 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004627 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 if (!D)
4629 return SourceRange();
4630
4631 SourceRange R = D->getSourceRange();
4632
4633 // Adjust the start of the location for declarations preceded by
4634 // declaration specifiers.
4635 SourceLocation StartLoc;
4636 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4637 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4638 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004639 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4641 StartLoc = TI->getTypeLoc().getLocStart();
4642 }
4643
4644 if (StartLoc.isValid() && R.getBegin().isValid() &&
4645 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4646 R.setBegin(StartLoc);
4647
4648 // FIXME: Multiple variables declared in a single declaration
4649 // currently lack the information needed to correctly determine their
4650 // ranges when accounting for the type-specifier. We use context
4651 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4652 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004653 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!cxcursor::isFirstInDeclGroup(C))
4655 R.setBegin(VD->getLocation());
4656 }
4657
4658 return R;
4659 }
4660
4661 return getRawCursorExtent(C);
4662}
4663
4664extern "C" {
4665
4666CXSourceRange clang_getCursorExtent(CXCursor C) {
4667 SourceRange R = getRawCursorExtent(C);
4668 if (R.isInvalid())
4669 return clang_getNullRange();
4670
4671 return cxloc::translateSourceRange(getCursorContext(C), R);
4672}
4673
4674CXCursor clang_getCursorReferenced(CXCursor C) {
4675 if (clang_isInvalid(C.kind))
4676 return clang_getNullCursor();
4677
4678 CXTranslationUnit tu = getCursorTU(C);
4679 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004680 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 if (!D)
4682 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004685 if (const ObjCPropertyImplDecl *PropImpl =
4686 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4688 return MakeCXCursor(Property, tu);
4689
4690 return C;
4691 }
4692
4693 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 const Expr *E = getCursorExpr(C);
4695 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 if (D) {
4697 CXCursor declCursor = MakeCXCursor(D, tu);
4698 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4699 declCursor);
4700 return declCursor;
4701 }
4702
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004703 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 return MakeCursorOverloadedDeclRef(Ovl, tu);
4705
4706 return clang_getNullCursor();
4707 }
4708
4709 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004710 const Stmt *S = getCursorStmt(C);
4711 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (LabelDecl *label = Goto->getLabel())
4713 if (LabelStmt *labelS = label->getStmt())
4714 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4715
4716 return clang_getNullCursor();
4717 }
4718
4719 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004720 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 return MakeMacroDefinitionCursor(Def, tu);
4722 }
4723
4724 if (!clang_isReference(C.kind))
4725 return clang_getNullCursor();
4726
4727 switch (C.kind) {
4728 case CXCursor_ObjCSuperClassRef:
4729 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4730
4731 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004732 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4733 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 return MakeCXCursor(Def, tu);
4735
4736 return MakeCXCursor(Prot, tu);
4737 }
4738
4739 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004740 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4741 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 return MakeCXCursor(Def, tu);
4743
4744 return MakeCXCursor(Class, tu);
4745 }
4746
4747 case CXCursor_TypeRef:
4748 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4749
4750 case CXCursor_TemplateRef:
4751 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4752
4753 case CXCursor_NamespaceRef:
4754 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4755
4756 case CXCursor_MemberRef:
4757 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4758
4759 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004760 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4762 tu ));
4763 }
4764
4765 case CXCursor_LabelRef:
4766 // FIXME: We end up faking the "parent" declaration here because we
4767 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004768 return MakeCXCursor(getCursorLabelRef(C).first,
4769 cxtu::getASTUnit(tu)->getASTContext()
4770 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 tu);
4772
4773 case CXCursor_OverloadedDeclRef:
4774 return C;
4775
4776 case CXCursor_VariableRef:
4777 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4778
4779 default:
4780 // We would prefer to enumerate all non-reference cursor kinds here.
4781 llvm_unreachable("Unhandled reference cursor kind");
4782 }
4783}
4784
4785CXCursor clang_getCursorDefinition(CXCursor C) {
4786 if (clang_isInvalid(C.kind))
4787 return clang_getNullCursor();
4788
4789 CXTranslationUnit TU = getCursorTU(C);
4790
4791 bool WasReference = false;
4792 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4793 C = clang_getCursorReferenced(C);
4794 WasReference = true;
4795 }
4796
4797 if (C.kind == CXCursor_MacroExpansion)
4798 return clang_getCursorReferenced(C);
4799
4800 if (!clang_isDeclaration(C.kind))
4801 return clang_getNullCursor();
4802
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 if (!D)
4805 return clang_getNullCursor();
4806
4807 switch (D->getKind()) {
4808 // Declaration kinds that don't really separate the notions of
4809 // declaration and definition.
4810 case Decl::Namespace:
4811 case Decl::Typedef:
4812 case Decl::TypeAlias:
4813 case Decl::TypeAliasTemplate:
4814 case Decl::TemplateTypeParm:
4815 case Decl::EnumConstant:
4816 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004817 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 case Decl::IndirectField:
4819 case Decl::ObjCIvar:
4820 case Decl::ObjCAtDefsField:
4821 case Decl::ImplicitParam:
4822 case Decl::ParmVar:
4823 case Decl::NonTypeTemplateParm:
4824 case Decl::TemplateTemplateParm:
4825 case Decl::ObjCCategoryImpl:
4826 case Decl::ObjCImplementation:
4827 case Decl::AccessSpec:
4828 case Decl::LinkageSpec:
4829 case Decl::ObjCPropertyImpl:
4830 case Decl::FileScopeAsm:
4831 case Decl::StaticAssert:
4832 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004833 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 case Decl::Label: // FIXME: Is this right??
4835 case Decl::ClassScopeFunctionSpecialization:
4836 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004837 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return C;
4839
4840 // Declaration kinds that don't make any sense here, but are
4841 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004842 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 case Decl::TranslationUnit:
4844 break;
4845
4846 // Declaration kinds for which the definition is not resolvable.
4847 case Decl::UnresolvedUsingTypename:
4848 case Decl::UnresolvedUsingValue:
4849 break;
4850
4851 case Decl::UsingDirective:
4852 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4853 TU);
4854
4855 case Decl::NamespaceAlias:
4856 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4857
4858 case Decl::Enum:
4859 case Decl::Record:
4860 case Decl::CXXRecord:
4861 case Decl::ClassTemplateSpecialization:
4862 case Decl::ClassTemplatePartialSpecialization:
4863 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4864 return MakeCXCursor(Def, TU);
4865 return clang_getNullCursor();
4866
4867 case Decl::Function:
4868 case Decl::CXXMethod:
4869 case Decl::CXXConstructor:
4870 case Decl::CXXDestructor:
4871 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004872 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004874 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 return clang_getNullCursor();
4876 }
4877
Larisse Voufo39a1e502013-08-06 01:03:05 +00004878 case Decl::Var:
4879 case Decl::VarTemplateSpecialization:
4880 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 return MakeCXCursor(Def, TU);
4884 return clang_getNullCursor();
4885 }
4886
4887 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004888 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4890 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4891 return clang_getNullCursor();
4892 }
4893
4894 case Decl::ClassTemplate: {
4895 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4896 ->getDefinition())
4897 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4898 TU);
4899 return clang_getNullCursor();
4900 }
4901
Larisse Voufo39a1e502013-08-06 01:03:05 +00004902 case Decl::VarTemplate: {
4903 if (VarDecl *Def =
4904 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4905 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4906 return clang_getNullCursor();
4907 }
4908
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 case Decl::Using:
4910 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4911 D->getLocation(), TU);
4912
4913 case Decl::UsingShadow:
4914 return clang_getCursorDefinition(
4915 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4916 TU));
4917
4918 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 if (Method->isThisDeclarationADefinition())
4921 return C;
4922
4923 // Dig out the method definition in the associated
4924 // @implementation, if we have it.
4925 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4928 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4929 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4930 Method->isInstanceMethod()))
4931 if (Def->isThisDeclarationADefinition())
4932 return MakeCXCursor(Def, TU);
4933
4934 return clang_getNullCursor();
4935 }
4936
4937 case Decl::ObjCCategory:
4938 if (ObjCCategoryImplDecl *Impl
4939 = cast<ObjCCategoryDecl>(D)->getImplementation())
4940 return MakeCXCursor(Impl, TU);
4941 return clang_getNullCursor();
4942
4943 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 return MakeCXCursor(Def, TU);
4946 return clang_getNullCursor();
4947
4948 case Decl::ObjCInterface: {
4949 // There are two notions of a "definition" for an Objective-C
4950 // class: the interface and its implementation. When we resolved a
4951 // reference to an Objective-C class, produce the @interface as
4952 // the definition; when we were provided with the interface,
4953 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004956 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 return MakeCXCursor(Def, TU);
4958 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4959 return MakeCXCursor(Impl, TU);
4960 return clang_getNullCursor();
4961 }
4962
4963 case Decl::ObjCProperty:
4964 // FIXME: We don't really know where to find the
4965 // ObjCPropertyImplDecls that implement this property.
4966 return clang_getNullCursor();
4967
4968 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004971 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 return MakeCXCursor(Def, TU);
4973
4974 return clang_getNullCursor();
4975
4976 case Decl::Friend:
4977 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4978 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4979 return clang_getNullCursor();
4980
4981 case Decl::FriendTemplate:
4982 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4983 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4984 return clang_getNullCursor();
4985 }
4986
4987 return clang_getNullCursor();
4988}
4989
4990unsigned clang_isCursorDefinition(CXCursor C) {
4991 if (!clang_isDeclaration(C.kind))
4992 return 0;
4993
4994 return clang_getCursorDefinition(C) == C;
4995}
4996
4997CXCursor clang_getCanonicalCursor(CXCursor C) {
4998 if (!clang_isDeclaration(C.kind))
4999 return C;
5000
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005001 if (const Decl *D = getCursorDecl(C)) {
5002 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005003 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5004 return MakeCXCursor(CatD, getCursorTU(C));
5005
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5007 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 return MakeCXCursor(IFD, getCursorTU(C));
5009
5010 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5011 }
5012
5013 return C;
5014}
5015
5016int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5017 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5018}
5019
5020unsigned clang_getNumOverloadedDecls(CXCursor C) {
5021 if (C.kind != CXCursor_OverloadedDeclRef)
5022 return 0;
5023
5024 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005025 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 return E->getNumDecls();
5027
5028 if (OverloadedTemplateStorage *S
5029 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5030 return S->size();
5031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005032 const Decl *D = Storage.get<const Decl *>();
5033 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 return Using->shadow_size();
5035
5036 return 0;
5037}
5038
5039CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5040 if (cursor.kind != CXCursor_OverloadedDeclRef)
5041 return clang_getNullCursor();
5042
5043 if (index >= clang_getNumOverloadedDecls(cursor))
5044 return clang_getNullCursor();
5045
5046 CXTranslationUnit TU = getCursorTU(cursor);
5047 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005048 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 return MakeCXCursor(E->decls_begin()[index], TU);
5050
5051 if (OverloadedTemplateStorage *S
5052 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5053 return MakeCXCursor(S->begin()[index], TU);
5054
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005055 const Decl *D = Storage.get<const Decl *>();
5056 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 // FIXME: This is, unfortunately, linear time.
5058 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5059 std::advance(Pos, index);
5060 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5061 }
5062
5063 return clang_getNullCursor();
5064}
5065
5066void clang_getDefinitionSpellingAndExtent(CXCursor C,
5067 const char **startBuf,
5068 const char **endBuf,
5069 unsigned *startLine,
5070 unsigned *startColumn,
5071 unsigned *endLine,
5072 unsigned *endColumn) {
5073 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5076
5077 SourceManager &SM = FD->getASTContext().getSourceManager();
5078 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5079 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5080 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5081 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5082 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5083 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5084}
5085
5086
5087CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5088 unsigned PieceIndex) {
5089 RefNamePieces Pieces;
5090
5091 switch (C.kind) {
5092 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005093 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5095 E->getQualifierLoc().getSourceRange());
5096 break;
5097
5098 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005099 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5101 E->getQualifierLoc().getSourceRange(),
5102 E->getOptionalExplicitTemplateArgs());
5103 break;
5104
5105 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005106 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005108 const Expr *Callee = OCE->getCallee();
5109 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 Callee = ICE->getSubExpr();
5111
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005112 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5114 DRE->getQualifierLoc().getSourceRange());
5115 }
5116 break;
5117
5118 default:
5119 break;
5120 }
5121
5122 if (Pieces.empty()) {
5123 if (PieceIndex == 0)
5124 return clang_getCursorExtent(C);
5125 } else if (PieceIndex < Pieces.size()) {
5126 SourceRange R = Pieces[PieceIndex];
5127 if (R.isValid())
5128 return cxloc::translateSourceRange(getCursorContext(C), R);
5129 }
5130
5131 return clang_getNullRange();
5132}
5133
5134void clang_enableStackTraces(void) {
5135 llvm::sys::PrintStackTraceOnErrorSignal();
5136}
5137
5138void clang_executeOnThread(void (*fn)(void*), void *user_data,
5139 unsigned stack_size) {
5140 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5141}
5142
5143} // end: extern "C"
5144
5145//===----------------------------------------------------------------------===//
5146// Token-based Operations.
5147//===----------------------------------------------------------------------===//
5148
5149/* CXToken layout:
5150 * int_data[0]: a CXTokenKind
5151 * int_data[1]: starting token location
5152 * int_data[2]: token length
5153 * int_data[3]: reserved
5154 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5155 * otherwise unused.
5156 */
5157extern "C" {
5158
5159CXTokenKind clang_getTokenKind(CXToken CXTok) {
5160 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5161}
5162
5163CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5164 switch (clang_getTokenKind(CXTok)) {
5165 case CXToken_Identifier:
5166 case CXToken_Keyword:
5167 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005168 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 ->getNameStart());
5170
5171 case CXToken_Literal: {
5172 // We have stashed the starting pointer in the ptr_data field. Use it.
5173 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005174 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 }
5176
5177 case CXToken_Punctuation:
5178 case CXToken_Comment:
5179 break;
5180 }
5181
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005182 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005183 LOG_BAD_TU(TU);
5184 return cxstring::createEmpty();
5185 }
5186
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 // We have to find the starting buffer pointer the hard way, by
5188 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005189 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005191 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005192
5193 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5194 std::pair<FileID, unsigned> LocInfo
5195 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5196 bool Invalid = false;
5197 StringRef Buffer
5198 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5199 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005200 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005201
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005202 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005203}
5204
5205CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005206 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005207 LOG_BAD_TU(TU);
5208 return clang_getNullLocation();
5209 }
5210
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005211 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 if (!CXXUnit)
5213 return clang_getNullLocation();
5214
5215 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5216 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5217}
5218
5219CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005220 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005221 LOG_BAD_TU(TU);
5222 return clang_getNullRange();
5223 }
5224
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 if (!CXXUnit)
5227 return clang_getNullRange();
5228
5229 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5230 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5231}
5232
5233static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5234 SmallVectorImpl<CXToken> &CXTokens) {
5235 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5236 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005237 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005239 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005240
5241 // Cannot tokenize across files.
5242 if (BeginLocInfo.first != EndLocInfo.first)
5243 return;
5244
5245 // Create a lexer
5246 bool Invalid = false;
5247 StringRef Buffer
5248 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5249 if (Invalid)
5250 return;
5251
5252 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5253 CXXUnit->getASTContext().getLangOpts(),
5254 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5255 Lex.SetCommentRetentionState(true);
5256
5257 // Lex tokens until we hit the end of the range.
5258 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5259 Token Tok;
5260 bool previousWasAt = false;
5261 do {
5262 // Lex the next token
5263 Lex.LexFromRawLexer(Tok);
5264 if (Tok.is(tok::eof))
5265 break;
5266
5267 // Initialize the CXToken.
5268 CXToken CXTok;
5269
5270 // - Common fields
5271 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5272 CXTok.int_data[2] = Tok.getLength();
5273 CXTok.int_data[3] = 0;
5274
5275 // - Kind-specific fields
5276 if (Tok.isLiteral()) {
5277 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005278 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 } else if (Tok.is(tok::raw_identifier)) {
5280 // Lookup the identifier to determine whether we have a keyword.
5281 IdentifierInfo *II
5282 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5283
5284 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5285 CXTok.int_data[0] = CXToken_Keyword;
5286 }
5287 else {
5288 CXTok.int_data[0] = Tok.is(tok::identifier)
5289 ? CXToken_Identifier
5290 : CXToken_Keyword;
5291 }
5292 CXTok.ptr_data = II;
5293 } else if (Tok.is(tok::comment)) {
5294 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005295 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 } else {
5297 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005298 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 }
5300 CXTokens.push_back(CXTok);
5301 previousWasAt = Tok.is(tok::at);
5302 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5303}
5304
5305void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5306 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005307 LOG_FUNC_SECTION {
5308 *Log << TU << ' ' << Range;
5309 }
5310
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005312 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 if (NumTokens)
5314 *NumTokens = 0;
5315
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005316 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005317 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005318 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005319 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005320
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005321 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 if (!CXXUnit || !Tokens || !NumTokens)
5323 return;
5324
5325 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5326
5327 SourceRange R = cxloc::translateCXSourceRange(Range);
5328 if (R.isInvalid())
5329 return;
5330
5331 SmallVector<CXToken, 32> CXTokens;
5332 getTokens(CXXUnit, R, CXTokens);
5333
5334 if (CXTokens.empty())
5335 return;
5336
5337 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5338 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5339 *NumTokens = CXTokens.size();
5340}
5341
5342void clang_disposeTokens(CXTranslationUnit TU,
5343 CXToken *Tokens, unsigned NumTokens) {
5344 free(Tokens);
5345}
5346
5347} // end: extern "C"
5348
5349//===----------------------------------------------------------------------===//
5350// Token annotation APIs.
5351//===----------------------------------------------------------------------===//
5352
Guy Benyei11169dd2012-12-18 14:30:41 +00005353static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5354 CXCursor parent,
5355 CXClientData client_data);
5356static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5357 CXClientData client_data);
5358
5359namespace {
5360class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 CXToken *Tokens;
5362 CXCursor *Cursors;
5363 unsigned NumTokens;
5364 unsigned TokIdx;
5365 unsigned PreprocessingTokIdx;
5366 CursorVisitor AnnotateVis;
5367 SourceManager &SrcMgr;
5368 bool HasContextSensitiveKeywords;
5369
5370 struct PostChildrenInfo {
5371 CXCursor Cursor;
5372 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005373 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 unsigned BeforeChildrenTokenIdx;
5375 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005376 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005377
5378 CXToken &getTok(unsigned Idx) {
5379 assert(Idx < NumTokens);
5380 return Tokens[Idx];
5381 }
5382 const CXToken &getTok(unsigned Idx) const {
5383 assert(Idx < NumTokens);
5384 return Tokens[Idx];
5385 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 bool MoreTokens() const { return TokIdx < NumTokens; }
5387 unsigned NextToken() const { return TokIdx; }
5388 void AdvanceToken() { ++TokIdx; }
5389 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005390 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 }
5392 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005393 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 }
5395 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005396 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005397 }
5398
5399 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005400 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 SourceRange);
5402
5403public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005404 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005405 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005406 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005408 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 AnnotateTokensVisitor, this,
5410 /*VisitPreprocessorLast=*/true,
5411 /*VisitIncludedEntities=*/false,
5412 RegionOfInterest,
5413 /*VisitDeclsOnly=*/false,
5414 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005415 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 HasContextSensitiveKeywords(false) { }
5417
5418 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5419 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5420 bool postVisitChildren(CXCursor cursor);
5421 void AnnotateTokens();
5422
5423 /// \brief Determine whether the annotator saw any cursors that have
5424 /// context-sensitive keywords.
5425 bool hasContextSensitiveKeywords() const {
5426 return HasContextSensitiveKeywords;
5427 }
5428
5429 ~AnnotateTokensWorker() {
5430 assert(PostChildrenInfos.empty());
5431 }
5432};
5433}
5434
5435void AnnotateTokensWorker::AnnotateTokens() {
5436 // Walk the AST within the region of interest, annotating tokens
5437 // along the way.
5438 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005439}
Guy Benyei11169dd2012-12-18 14:30:41 +00005440
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005441static inline void updateCursorAnnotation(CXCursor &Cursor,
5442 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005443 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005445 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005446}
5447
5448/// \brief It annotates and advances tokens with a cursor until the comparison
5449//// between the cursor location and the source range is the same as
5450/// \arg compResult.
5451///
5452/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5453/// Pass RangeOverlap to annotate tokens inside a range.
5454void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5455 RangeComparisonResult compResult,
5456 SourceRange range) {
5457 while (MoreTokens()) {
5458 const unsigned I = NextToken();
5459 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005460 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5461 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005462
5463 SourceLocation TokLoc = GetTokenLoc(I);
5464 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005465 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 AdvanceToken();
5467 continue;
5468 }
5469 break;
5470 }
5471}
5472
5473/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005474/// \returns true if it advanced beyond all macro tokens, false otherwise.
5475bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 CXCursor updateC,
5477 RangeComparisonResult compResult,
5478 SourceRange range) {
5479 assert(MoreTokens());
5480 assert(isFunctionMacroToken(NextToken()) &&
5481 "Should be called only for macro arg tokens");
5482
5483 // This works differently than annotateAndAdvanceTokens; because expanded
5484 // macro arguments can have arbitrary translation-unit source order, we do not
5485 // advance the token index one by one until a token fails the range test.
5486 // We only advance once past all of the macro arg tokens if all of them
5487 // pass the range test. If one of them fails we keep the token index pointing
5488 // at the start of the macro arg tokens so that the failing token will be
5489 // annotated by a subsequent annotation try.
5490
5491 bool atLeastOneCompFail = false;
5492
5493 unsigned I = NextToken();
5494 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5495 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5496 if (TokLoc.isFileID())
5497 continue; // not macro arg token, it's parens or comma.
5498 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5499 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5500 Cursors[I] = updateC;
5501 } else
5502 atLeastOneCompFail = true;
5503 }
5504
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005505 if (atLeastOneCompFail)
5506 return false;
5507
5508 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5509 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005510}
5511
5512enum CXChildVisitResult
5513AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 SourceRange cursorRange = getRawCursorExtent(cursor);
5515 if (cursorRange.isInvalid())
5516 return CXChildVisit_Recurse;
5517
5518 if (!HasContextSensitiveKeywords) {
5519 // Objective-C properties can have context-sensitive keywords.
5520 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005521 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5523 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5524 }
5525 // Objective-C methods can have context-sensitive keywords.
5526 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5527 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005528 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5530 if (Method->getObjCDeclQualifier())
5531 HasContextSensitiveKeywords = true;
5532 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005533 for (const auto *P : Method->params()) {
5534 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 HasContextSensitiveKeywords = true;
5536 break;
5537 }
5538 }
5539 }
5540 }
5541 }
5542 // C++ methods can have context-sensitive keywords.
5543 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005544 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5546 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5547 HasContextSensitiveKeywords = true;
5548 }
5549 }
5550 // C++ classes can have context-sensitive keywords.
5551 else if (cursor.kind == CXCursor_StructDecl ||
5552 cursor.kind == CXCursor_ClassDecl ||
5553 cursor.kind == CXCursor_ClassTemplate ||
5554 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005555 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 if (D->hasAttr<FinalAttr>())
5557 HasContextSensitiveKeywords = true;
5558 }
5559 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005560
5561 // Don't override a property annotation with its getter/setter method.
5562 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5563 parent.kind == CXCursor_ObjCPropertyDecl)
5564 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005565
5566 if (clang_isPreprocessing(cursor.kind)) {
5567 // Items in the preprocessing record are kept separate from items in
5568 // declarations, so we keep a separate token index.
5569 unsigned SavedTokIdx = TokIdx;
5570 TokIdx = PreprocessingTokIdx;
5571
5572 // Skip tokens up until we catch up to the beginning of the preprocessing
5573 // entry.
5574 while (MoreTokens()) {
5575 const unsigned I = NextToken();
5576 SourceLocation TokLoc = GetTokenLoc(I);
5577 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5578 case RangeBefore:
5579 AdvanceToken();
5580 continue;
5581 case RangeAfter:
5582 case RangeOverlap:
5583 break;
5584 }
5585 break;
5586 }
5587
5588 // Look at all of the tokens within this range.
5589 while (MoreTokens()) {
5590 const unsigned I = NextToken();
5591 SourceLocation TokLoc = GetTokenLoc(I);
5592 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5593 case RangeBefore:
5594 llvm_unreachable("Infeasible");
5595 case RangeAfter:
5596 break;
5597 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005598 // For macro expansions, just note where the beginning of the macro
5599 // expansion occurs.
5600 if (cursor.kind == CXCursor_MacroExpansion) {
5601 if (TokLoc == cursorRange.getBegin())
5602 Cursors[I] = cursor;
5603 AdvanceToken();
5604 break;
5605 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005606 // We may have already annotated macro names inside macro definitions.
5607 if (Cursors[I].kind != CXCursor_MacroExpansion)
5608 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 continue;
5611 }
5612 break;
5613 }
5614
5615 // Save the preprocessing token index; restore the non-preprocessing
5616 // token index.
5617 PreprocessingTokIdx = TokIdx;
5618 TokIdx = SavedTokIdx;
5619 return CXChildVisit_Recurse;
5620 }
5621
5622 if (cursorRange.isInvalid())
5623 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005624
5625 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 const enum CXCursorKind K = clang_getCursorKind(parent);
5628 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005629 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5630 // Attributes are annotated out-of-order, skip tokens until we reach it.
5631 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 ? clang_getNullCursor() : parent;
5633
5634 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5635
5636 // Avoid having the cursor of an expression "overwrite" the annotation of the
5637 // variable declaration that it belongs to.
5638 // This can happen for C++ constructor expressions whose range generally
5639 // include the variable declaration, e.g.:
5640 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005641 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005642 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005643 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 const unsigned I = NextToken();
5645 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5646 E->getLocStart() == D->getLocation() &&
5647 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005648 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 AdvanceToken();
5650 }
5651 }
5652 }
5653
5654 // Before recursing into the children keep some state that we are going
5655 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5656 // extra work after the child nodes are visited.
5657 // Note that we don't call VisitChildren here to avoid traversing statements
5658 // code-recursively which can blow the stack.
5659
5660 PostChildrenInfo Info;
5661 Info.Cursor = cursor;
5662 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005663 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 Info.BeforeChildrenTokenIdx = NextToken();
5665 PostChildrenInfos.push_back(Info);
5666
5667 return CXChildVisit_Recurse;
5668}
5669
5670bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5671 if (PostChildrenInfos.empty())
5672 return false;
5673 const PostChildrenInfo &Info = PostChildrenInfos.back();
5674 if (!clang_equalCursors(Info.Cursor, cursor))
5675 return false;
5676
5677 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5678 const unsigned AfterChildren = NextToken();
5679 SourceRange cursorRange = Info.CursorRange;
5680
5681 // Scan the tokens that are at the end of the cursor, but are not captured
5682 // but the child cursors.
5683 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5684
5685 // Scan the tokens that are at the beginning of the cursor, but are not
5686 // capture by the child cursors.
5687 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5688 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5689 break;
5690
5691 Cursors[I] = cursor;
5692 }
5693
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005694 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5695 // encountered the attribute cursor.
5696 if (clang_isAttribute(cursor.kind))
5697 TokIdx = Info.BeforeReachingCursorIdx;
5698
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 PostChildrenInfos.pop_back();
5700 return false;
5701}
5702
5703static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5704 CXCursor parent,
5705 CXClientData client_data) {
5706 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5707}
5708
5709static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5710 CXClientData client_data) {
5711 return static_cast<AnnotateTokensWorker*>(client_data)->
5712 postVisitChildren(cursor);
5713}
5714
5715namespace {
5716
5717/// \brief Uses the macro expansions in the preprocessing record to find
5718/// and mark tokens that are macro arguments. This info is used by the
5719/// AnnotateTokensWorker.
5720class MarkMacroArgTokensVisitor {
5721 SourceManager &SM;
5722 CXToken *Tokens;
5723 unsigned NumTokens;
5724 unsigned CurIdx;
5725
5726public:
5727 MarkMacroArgTokensVisitor(SourceManager &SM,
5728 CXToken *tokens, unsigned numTokens)
5729 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5730
5731 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5732 if (cursor.kind != CXCursor_MacroExpansion)
5733 return CXChildVisit_Continue;
5734
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005735 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 if (macroRange.getBegin() == macroRange.getEnd())
5737 return CXChildVisit_Continue; // it's not a function macro.
5738
5739 for (; CurIdx < NumTokens; ++CurIdx) {
5740 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5741 macroRange.getBegin()))
5742 break;
5743 }
5744
5745 if (CurIdx == NumTokens)
5746 return CXChildVisit_Break;
5747
5748 for (; CurIdx < NumTokens; ++CurIdx) {
5749 SourceLocation tokLoc = getTokenLoc(CurIdx);
5750 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5751 break;
5752
5753 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5754 }
5755
5756 if (CurIdx == NumTokens)
5757 return CXChildVisit_Break;
5758
5759 return CXChildVisit_Continue;
5760 }
5761
5762private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005763 CXToken &getTok(unsigned Idx) {
5764 assert(Idx < NumTokens);
5765 return Tokens[Idx];
5766 }
5767 const CXToken &getTok(unsigned Idx) const {
5768 assert(Idx < NumTokens);
5769 return Tokens[Idx];
5770 }
5771
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005773 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 }
5775
5776 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5777 // The third field is reserved and currently not used. Use it here
5778 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005779 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 }
5781};
5782
5783} // end anonymous namespace
5784
5785static CXChildVisitResult
5786MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5787 CXClientData client_data) {
5788 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5789 parent);
5790}
5791
5792namespace {
5793 struct clang_annotateTokens_Data {
5794 CXTranslationUnit TU;
5795 ASTUnit *CXXUnit;
5796 CXToken *Tokens;
5797 unsigned NumTokens;
5798 CXCursor *Cursors;
5799 };
5800}
5801
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005802/// \brief Used by \c annotatePreprocessorTokens.
5803/// \returns true if lexing was finished, false otherwise.
5804static bool lexNext(Lexer &Lex, Token &Tok,
5805 unsigned &NextIdx, unsigned NumTokens) {
5806 if (NextIdx >= NumTokens)
5807 return true;
5808
5809 ++NextIdx;
5810 Lex.LexFromRawLexer(Tok);
5811 if (Tok.is(tok::eof))
5812 return true;
5813
5814 return false;
5815}
5816
Guy Benyei11169dd2012-12-18 14:30:41 +00005817static void annotatePreprocessorTokens(CXTranslationUnit TU,
5818 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005819 CXCursor *Cursors,
5820 CXToken *Tokens,
5821 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005822 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005823
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005824 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005825 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5826 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005827 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005829 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005830
5831 if (BeginLocInfo.first != EndLocInfo.first)
5832 return;
5833
5834 StringRef Buffer;
5835 bool Invalid = false;
5836 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5837 if (Buffer.empty() || Invalid)
5838 return;
5839
5840 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5841 CXXUnit->getASTContext().getLangOpts(),
5842 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5843 Buffer.end());
5844 Lex.SetCommentRetentionState(true);
5845
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005846 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 // Lex tokens in raw mode until we hit the end of the range, to avoid
5848 // entering #includes or expanding macros.
5849 while (true) {
5850 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005851 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5852 break;
5853 unsigned TokIdx = NextIdx-1;
5854 assert(Tok.getLocation() ==
5855 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005856
5857 reprocess:
5858 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005859 // We have found a preprocessing directive. Annotate the tokens
5860 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005861 //
5862 // FIXME: Some simple tests here could identify macro definitions and
5863 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005864
5865 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005866 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5867 break;
5868
Craig Topper69186e72014-06-08 08:38:04 +00005869 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005870 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005871 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5872 break;
5873
5874 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005875 IdentifierInfo &II =
5876 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005877 SourceLocation MappedTokLoc =
5878 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5879 MI = getMacroInfo(II, MappedTokLoc, TU);
5880 }
5881 }
5882
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005883 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005885 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5886 finished = true;
5887 break;
5888 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005889 // If we are in a macro definition, check if the token was ever a
5890 // macro name and annotate it if that's the case.
5891 if (MI) {
5892 SourceLocation SaveLoc = Tok.getLocation();
5893 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5894 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5895 Tok.setLocation(SaveLoc);
5896 if (MacroDef)
5897 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5898 Tok.getLocation(), TU);
5899 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005900 } while (!Tok.isAtStartOfLine());
5901
5902 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5903 assert(TokIdx <= LastIdx);
5904 SourceLocation EndLoc =
5905 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5906 CXCursor Cursor =
5907 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5908
5909 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005910 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005911
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005912 if (finished)
5913 break;
5914 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 }
5917}
5918
5919// This gets run a separate thread to avoid stack blowout.
5920static void clang_annotateTokensImpl(void *UserData) {
5921 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5922 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5923 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5924 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5925 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5926
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005927 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005928 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5929 setThreadBackgroundPriority();
5930
5931 // Determine the region of interest, which contains all of the tokens.
5932 SourceRange RegionOfInterest;
5933 RegionOfInterest.setBegin(
5934 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5935 RegionOfInterest.setEnd(
5936 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5937 Tokens[NumTokens-1])));
5938
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 // Relex the tokens within the source range to look for preprocessing
5940 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005941 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005942
5943 // If begin location points inside a macro argument, set it to the expansion
5944 // location so we can have the full context when annotating semantically.
5945 {
5946 SourceManager &SM = CXXUnit->getSourceManager();
5947 SourceLocation Loc =
5948 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5949 if (Loc.isMacroID())
5950 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5951 }
5952
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5954 // Search and mark tokens that are macro argument expansions.
5955 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5956 Tokens, NumTokens);
5957 CursorVisitor MacroArgMarker(TU,
5958 MarkMacroArgTokensVisitorDelegate, &Visitor,
5959 /*VisitPreprocessorLast=*/true,
5960 /*VisitIncludedEntities=*/false,
5961 RegionOfInterest);
5962 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5963 }
5964
5965 // Annotate all of the source locations in the region of interest that map to
5966 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005967 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005968
5969 // FIXME: We use a ridiculous stack size here because the data-recursion
5970 // algorithm uses a large stack frame than the non-data recursive version,
5971 // and AnnotationTokensWorker currently transforms the data-recursion
5972 // algorithm back into a traditional recursion by explicitly calling
5973 // VisitChildren(). We will need to remove this explicit recursive call.
5974 W.AnnotateTokens();
5975
5976 // If we ran into any entities that involve context-sensitive keywords,
5977 // take another pass through the tokens to mark them as such.
5978 if (W.hasContextSensitiveKeywords()) {
5979 for (unsigned I = 0; I != NumTokens; ++I) {
5980 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5981 continue;
5982
5983 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5984 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005985 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005986 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5987 if (Property->getPropertyAttributesAsWritten() != 0 &&
5988 llvm::StringSwitch<bool>(II->getName())
5989 .Case("readonly", true)
5990 .Case("assign", true)
5991 .Case("unsafe_unretained", true)
5992 .Case("readwrite", true)
5993 .Case("retain", true)
5994 .Case("copy", true)
5995 .Case("nonatomic", true)
5996 .Case("atomic", true)
5997 .Case("getter", true)
5998 .Case("setter", true)
5999 .Case("strong", true)
6000 .Case("weak", true)
6001 .Default(false))
6002 Tokens[I].int_data[0] = CXToken_Keyword;
6003 }
6004 continue;
6005 }
6006
6007 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6008 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6009 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6010 if (llvm::StringSwitch<bool>(II->getName())
6011 .Case("in", true)
6012 .Case("out", true)
6013 .Case("inout", true)
6014 .Case("oneway", true)
6015 .Case("bycopy", true)
6016 .Case("byref", true)
6017 .Default(false))
6018 Tokens[I].int_data[0] = CXToken_Keyword;
6019 continue;
6020 }
6021
6022 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6023 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6024 Tokens[I].int_data[0] = CXToken_Keyword;
6025 continue;
6026 }
6027 }
6028 }
6029}
6030
6031extern "C" {
6032
6033void clang_annotateTokens(CXTranslationUnit TU,
6034 CXToken *Tokens, unsigned NumTokens,
6035 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006036 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006037 LOG_BAD_TU(TU);
6038 return;
6039 }
6040 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006041 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006042 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006043 }
6044
6045 LOG_FUNC_SECTION {
6046 *Log << TU << ' ';
6047 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6048 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6049 *Log << clang_getRange(bloc, eloc);
6050 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006051
6052 // Any token we don't specifically annotate will have a NULL cursor.
6053 CXCursor C = clang_getNullCursor();
6054 for (unsigned I = 0; I != NumTokens; ++I)
6055 Cursors[I] = C;
6056
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006057 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006058 if (!CXXUnit)
6059 return;
6060
6061 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6062
6063 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6064 llvm::CrashRecoveryContext CRC;
6065 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6066 GetSafetyThreadStackSize() * 2)) {
6067 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6068 }
6069}
6070
6071} // end: extern "C"
6072
6073//===----------------------------------------------------------------------===//
6074// Operations for querying linkage of a cursor.
6075//===----------------------------------------------------------------------===//
6076
6077extern "C" {
6078CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6079 if (!clang_isDeclaration(cursor.kind))
6080 return CXLinkage_Invalid;
6081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006082 const Decl *D = cxcursor::getCursorDecl(cursor);
6083 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006084 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006085 case NoLinkage:
6086 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 case InternalLinkage: return CXLinkage_Internal;
6088 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6089 case ExternalLinkage: return CXLinkage_External;
6090 };
6091
6092 return CXLinkage_Invalid;
6093}
6094} // end: extern "C"
6095
6096//===----------------------------------------------------------------------===//
6097// Operations for querying language of a cursor.
6098//===----------------------------------------------------------------------===//
6099
6100static CXLanguageKind getDeclLanguage(const Decl *D) {
6101 if (!D)
6102 return CXLanguage_C;
6103
6104 switch (D->getKind()) {
6105 default:
6106 break;
6107 case Decl::ImplicitParam:
6108 case Decl::ObjCAtDefsField:
6109 case Decl::ObjCCategory:
6110 case Decl::ObjCCategoryImpl:
6111 case Decl::ObjCCompatibleAlias:
6112 case Decl::ObjCImplementation:
6113 case Decl::ObjCInterface:
6114 case Decl::ObjCIvar:
6115 case Decl::ObjCMethod:
6116 case Decl::ObjCProperty:
6117 case Decl::ObjCPropertyImpl:
6118 case Decl::ObjCProtocol:
6119 return CXLanguage_ObjC;
6120 case Decl::CXXConstructor:
6121 case Decl::CXXConversion:
6122 case Decl::CXXDestructor:
6123 case Decl::CXXMethod:
6124 case Decl::CXXRecord:
6125 case Decl::ClassTemplate:
6126 case Decl::ClassTemplatePartialSpecialization:
6127 case Decl::ClassTemplateSpecialization:
6128 case Decl::Friend:
6129 case Decl::FriendTemplate:
6130 case Decl::FunctionTemplate:
6131 case Decl::LinkageSpec:
6132 case Decl::Namespace:
6133 case Decl::NamespaceAlias:
6134 case Decl::NonTypeTemplateParm:
6135 case Decl::StaticAssert:
6136 case Decl::TemplateTemplateParm:
6137 case Decl::TemplateTypeParm:
6138 case Decl::UnresolvedUsingTypename:
6139 case Decl::UnresolvedUsingValue:
6140 case Decl::Using:
6141 case Decl::UsingDirective:
6142 case Decl::UsingShadow:
6143 return CXLanguage_CPlusPlus;
6144 }
6145
6146 return CXLanguage_C;
6147}
6148
6149extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006150
6151static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6152 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6153 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006154
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006155 switch (D->getAvailability()) {
6156 case AR_Available:
6157 case AR_NotYetIntroduced:
6158 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006159 return getCursorAvailabilityForDecl(
6160 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006161 return CXAvailability_Available;
6162
6163 case AR_Deprecated:
6164 return CXAvailability_Deprecated;
6165
6166 case AR_Unavailable:
6167 return CXAvailability_NotAvailable;
6168 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006169
6170 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006171}
6172
Guy Benyei11169dd2012-12-18 14:30:41 +00006173enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6174 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006175 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6176 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006177
6178 return CXAvailability_Available;
6179}
6180
6181static CXVersion convertVersion(VersionTuple In) {
6182 CXVersion Out = { -1, -1, -1 };
6183 if (In.empty())
6184 return Out;
6185
6186 Out.Major = In.getMajor();
6187
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006188 Optional<unsigned> Minor = In.getMinor();
6189 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 Out.Minor = *Minor;
6191 else
6192 return Out;
6193
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006194 Optional<unsigned> Subminor = In.getSubminor();
6195 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 Out.Subminor = *Subminor;
6197
6198 return Out;
6199}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006200
6201static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6202 int *always_deprecated,
6203 CXString *deprecated_message,
6204 int *always_unavailable,
6205 CXString *unavailable_message,
6206 CXPlatformAvailability *availability,
6207 int availability_size) {
6208 bool HadAvailAttr = false;
6209 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006210 for (auto A : D->attrs()) {
6211 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006212 HadAvailAttr = true;
6213 if (always_deprecated)
6214 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006215 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006216 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006217 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006218 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006219 continue;
6220 }
6221
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006222 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006223 HadAvailAttr = true;
6224 if (always_unavailable)
6225 *always_unavailable = 1;
6226 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006227 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006228 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6229 }
6230 continue;
6231 }
6232
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006233 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006234 HadAvailAttr = true;
6235 if (N < availability_size) {
6236 availability[N].Platform
6237 = cxstring::createDup(Avail->getPlatform()->getName());
6238 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6239 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6240 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6241 availability[N].Unavailable = Avail->getUnavailable();
6242 availability[N].Message = cxstring::createDup(Avail->getMessage());
6243 }
6244 ++N;
6245 }
6246 }
6247
6248 if (!HadAvailAttr)
6249 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6250 return getCursorPlatformAvailabilityForDecl(
6251 cast<Decl>(EnumConst->getDeclContext()),
6252 always_deprecated,
6253 deprecated_message,
6254 always_unavailable,
6255 unavailable_message,
6256 availability,
6257 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006258
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006259 return N;
6260}
6261
Guy Benyei11169dd2012-12-18 14:30:41 +00006262int clang_getCursorPlatformAvailability(CXCursor cursor,
6263 int *always_deprecated,
6264 CXString *deprecated_message,
6265 int *always_unavailable,
6266 CXString *unavailable_message,
6267 CXPlatformAvailability *availability,
6268 int availability_size) {
6269 if (always_deprecated)
6270 *always_deprecated = 0;
6271 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006272 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006273 if (always_unavailable)
6274 *always_unavailable = 0;
6275 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006276 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006277
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 if (!clang_isDeclaration(cursor.kind))
6279 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006281 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006282 if (!D)
6283 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006284
6285 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6286 deprecated_message,
6287 always_unavailable,
6288 unavailable_message,
6289 availability,
6290 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006291}
6292
6293void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6294 clang_disposeString(availability->Platform);
6295 clang_disposeString(availability->Message);
6296}
6297
6298CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6299 if (clang_isDeclaration(cursor.kind))
6300 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6301
6302 return CXLanguage_Invalid;
6303}
6304
6305 /// \brief If the given cursor is the "templated" declaration
6306 /// descibing a class or function template, return the class or
6307 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006308static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006310 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006312 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6314 return FunTmpl;
6315
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006316 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6318 return ClassTmpl;
6319
6320 return D;
6321}
6322
6323CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6324 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006325 if (const Decl *D = getCursorDecl(cursor)) {
6326 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 if (!DC)
6328 return clang_getNullCursor();
6329
6330 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6331 getCursorTU(cursor));
6332 }
6333 }
6334
6335 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006336 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 return MakeCXCursor(D, getCursorTU(cursor));
6338 }
6339
6340 return clang_getNullCursor();
6341}
6342
6343CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6344 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006345 if (const Decl *D = getCursorDecl(cursor)) {
6346 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 if (!DC)
6348 return clang_getNullCursor();
6349
6350 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6351 getCursorTU(cursor));
6352 }
6353 }
6354
6355 // FIXME: Note that we can't easily compute the lexical context of a
6356 // statement or expression, so we return nothing.
6357 return clang_getNullCursor();
6358}
6359
6360CXFile clang_getIncludedFile(CXCursor cursor) {
6361 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006362 return nullptr;
6363
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006364 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006365 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006366}
6367
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006368unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6369 if (C.kind != CXCursor_ObjCPropertyDecl)
6370 return CXObjCPropertyAttr_noattr;
6371
6372 unsigned Result = CXObjCPropertyAttr_noattr;
6373 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6374 ObjCPropertyDecl::PropertyAttributeKind Attr =
6375 PD->getPropertyAttributesAsWritten();
6376
6377#define SET_CXOBJCPROP_ATTR(A) \
6378 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6379 Result |= CXObjCPropertyAttr_##A
6380 SET_CXOBJCPROP_ATTR(readonly);
6381 SET_CXOBJCPROP_ATTR(getter);
6382 SET_CXOBJCPROP_ATTR(assign);
6383 SET_CXOBJCPROP_ATTR(readwrite);
6384 SET_CXOBJCPROP_ATTR(retain);
6385 SET_CXOBJCPROP_ATTR(copy);
6386 SET_CXOBJCPROP_ATTR(nonatomic);
6387 SET_CXOBJCPROP_ATTR(setter);
6388 SET_CXOBJCPROP_ATTR(atomic);
6389 SET_CXOBJCPROP_ATTR(weak);
6390 SET_CXOBJCPROP_ATTR(strong);
6391 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6392#undef SET_CXOBJCPROP_ATTR
6393
6394 return Result;
6395}
6396
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006397unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6398 if (!clang_isDeclaration(C.kind))
6399 return CXObjCDeclQualifier_None;
6400
6401 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6402 const Decl *D = getCursorDecl(C);
6403 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6404 QT = MD->getObjCDeclQualifier();
6405 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6406 QT = PD->getObjCDeclQualifier();
6407 if (QT == Decl::OBJC_TQ_None)
6408 return CXObjCDeclQualifier_None;
6409
6410 unsigned Result = CXObjCDeclQualifier_None;
6411 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6412 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6413 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6414 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6415 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6416 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6417
6418 return Result;
6419}
6420
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006421unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6422 if (!clang_isDeclaration(C.kind))
6423 return 0;
6424
6425 const Decl *D = getCursorDecl(C);
6426 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6427 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6428 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6429 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6430
6431 return 0;
6432}
6433
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006434unsigned clang_Cursor_isVariadic(CXCursor C) {
6435 if (!clang_isDeclaration(C.kind))
6436 return 0;
6437
6438 const Decl *D = getCursorDecl(C);
6439 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6440 return FD->isVariadic();
6441 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6442 return MD->isVariadic();
6443
6444 return 0;
6445}
6446
Guy Benyei11169dd2012-12-18 14:30:41 +00006447CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6448 if (!clang_isDeclaration(C.kind))
6449 return clang_getNullRange();
6450
6451 const Decl *D = getCursorDecl(C);
6452 ASTContext &Context = getCursorContext(C);
6453 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6454 if (!RC)
6455 return clang_getNullRange();
6456
6457 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6458}
6459
6460CXString clang_Cursor_getRawCommentText(CXCursor C) {
6461 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006462 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006463
6464 const Decl *D = getCursorDecl(C);
6465 ASTContext &Context = getCursorContext(C);
6466 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6467 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6468 StringRef();
6469
6470 // Don't duplicate the string because RawText points directly into source
6471 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006472 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006473}
6474
6475CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6476 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006477 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006478
6479 const Decl *D = getCursorDecl(C);
6480 const ASTContext &Context = getCursorContext(C);
6481 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6482
6483 if (RC) {
6484 StringRef BriefText = RC->getBriefText(Context);
6485
6486 // Don't duplicate the string because RawComment ensures that this memory
6487 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006488 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 }
6490
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006491 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006492}
6493
Guy Benyei11169dd2012-12-18 14:30:41 +00006494CXModule clang_Cursor_getModule(CXCursor C) {
6495 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006496 if (const ImportDecl *ImportD =
6497 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return ImportD->getImportedModule();
6499 }
6500
Craig Topper69186e72014-06-08 08:38:04 +00006501 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006502}
6503
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006504CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6505 if (isNotUsableTU(TU)) {
6506 LOG_BAD_TU(TU);
6507 return nullptr;
6508 }
6509 if (!File)
6510 return nullptr;
6511 FileEntry *FE = static_cast<FileEntry *>(File);
6512
6513 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6514 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6515 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6516
6517 if (Module *Mod = Header.getModule()) {
6518 if (Header.getRole() != ModuleMap::ExcludedHeader)
6519 return Mod;
6520 }
6521 return nullptr;
6522}
6523
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006524CXFile clang_Module_getASTFile(CXModule CXMod) {
6525 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006526 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006527 Module *Mod = static_cast<Module*>(CXMod);
6528 return const_cast<FileEntry *>(Mod->getASTFile());
6529}
6530
Guy Benyei11169dd2012-12-18 14:30:41 +00006531CXModule clang_Module_getParent(CXModule CXMod) {
6532 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006533 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006534 Module *Mod = static_cast<Module*>(CXMod);
6535 return Mod->Parent;
6536}
6537
6538CXString clang_Module_getName(CXModule CXMod) {
6539 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006540 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006541 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006542 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006543}
6544
6545CXString clang_Module_getFullName(CXModule CXMod) {
6546 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006547 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006549 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006550}
6551
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006552int clang_Module_isSystem(CXModule CXMod) {
6553 if (!CXMod)
6554 return 0;
6555 Module *Mod = static_cast<Module*>(CXMod);
6556 return Mod->IsSystem;
6557}
6558
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006559unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6560 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006561 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006562 LOG_BAD_TU(TU);
6563 return 0;
6564 }
6565 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 return 0;
6567 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006568 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6569 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6570 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006571}
6572
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006573CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6574 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006575 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006576 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006577 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006578 }
6579 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006580 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006582 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006583
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006584 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6585 if (Index < TopHeaders.size())
6586 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006587
Craig Topper69186e72014-06-08 08:38:04 +00006588 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006589}
6590
6591} // end: extern "C"
6592
6593//===----------------------------------------------------------------------===//
6594// C++ AST instrospection.
6595//===----------------------------------------------------------------------===//
6596
6597extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006598unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6599 if (!clang_isDeclaration(C.kind))
6600 return 0;
6601
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006602 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006603 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006604 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006605 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6606}
6607
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006608unsigned clang_CXXMethod_isConst(CXCursor C) {
6609 if (!clang_isDeclaration(C.kind))
6610 return 0;
6611
6612 const Decl *D = cxcursor::getCursorDecl(C);
6613 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006614 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006615 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6616}
6617
Guy Benyei11169dd2012-12-18 14:30:41 +00006618unsigned clang_CXXMethod_isStatic(CXCursor C) {
6619 if (!clang_isDeclaration(C.kind))
6620 return 0;
6621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006622 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006623 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006624 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 return (Method && Method->isStatic()) ? 1 : 0;
6626}
6627
6628unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6629 if (!clang_isDeclaration(C.kind))
6630 return 0;
6631
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006632 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006633 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006634 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006635 return (Method && Method->isVirtual()) ? 1 : 0;
6636}
6637} // end: extern "C"
6638
6639//===----------------------------------------------------------------------===//
6640// Attribute introspection.
6641//===----------------------------------------------------------------------===//
6642
6643extern "C" {
6644CXType clang_getIBOutletCollectionType(CXCursor C) {
6645 if (C.kind != CXCursor_IBOutletCollectionAttr)
6646 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6647
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006648 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006649 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6650
6651 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6652}
6653} // end: extern "C"
6654
6655//===----------------------------------------------------------------------===//
6656// Inspecting memory usage.
6657//===----------------------------------------------------------------------===//
6658
6659typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6660
6661static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6662 enum CXTUResourceUsageKind k,
6663 unsigned long amount) {
6664 CXTUResourceUsageEntry entry = { k, amount };
6665 entries.push_back(entry);
6666}
6667
6668extern "C" {
6669
6670const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6671 const char *str = "";
6672 switch (kind) {
6673 case CXTUResourceUsage_AST:
6674 str = "ASTContext: expressions, declarations, and types";
6675 break;
6676 case CXTUResourceUsage_Identifiers:
6677 str = "ASTContext: identifiers";
6678 break;
6679 case CXTUResourceUsage_Selectors:
6680 str = "ASTContext: selectors";
6681 break;
6682 case CXTUResourceUsage_GlobalCompletionResults:
6683 str = "Code completion: cached global results";
6684 break;
6685 case CXTUResourceUsage_SourceManagerContentCache:
6686 str = "SourceManager: content cache allocator";
6687 break;
6688 case CXTUResourceUsage_AST_SideTables:
6689 str = "ASTContext: side tables";
6690 break;
6691 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6692 str = "SourceManager: malloc'ed memory buffers";
6693 break;
6694 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6695 str = "SourceManager: mmap'ed memory buffers";
6696 break;
6697 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6698 str = "ExternalASTSource: malloc'ed memory buffers";
6699 break;
6700 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6701 str = "ExternalASTSource: mmap'ed memory buffers";
6702 break;
6703 case CXTUResourceUsage_Preprocessor:
6704 str = "Preprocessor: malloc'ed memory";
6705 break;
6706 case CXTUResourceUsage_PreprocessingRecord:
6707 str = "Preprocessor: PreprocessingRecord";
6708 break;
6709 case CXTUResourceUsage_SourceManager_DataStructures:
6710 str = "SourceManager: data structures and tables";
6711 break;
6712 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6713 str = "Preprocessor: header search tables";
6714 break;
6715 }
6716 return str;
6717}
6718
6719CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006720 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006721 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006722 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 return usage;
6724 }
6725
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006726 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006727 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006728 ASTContext &astContext = astUnit->getASTContext();
6729
6730 // How much memory is used by AST nodes and types?
6731 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6732 (unsigned long) astContext.getASTAllocatedMemory());
6733
6734 // How much memory is used by identifiers?
6735 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6736 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6737
6738 // How much memory is used for selectors?
6739 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6740 (unsigned long) astContext.Selectors.getTotalMemory());
6741
6742 // How much memory is used by ASTContext's side tables?
6743 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6744 (unsigned long) astContext.getSideTableAllocatedMemory());
6745
6746 // How much memory is used for caching global code completion results?
6747 unsigned long completionBytes = 0;
6748 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006749 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006750 completionBytes = completionAllocator->getTotalMemory();
6751 }
6752 createCXTUResourceUsageEntry(*entries,
6753 CXTUResourceUsage_GlobalCompletionResults,
6754 completionBytes);
6755
6756 // How much memory is being used by SourceManager's content cache?
6757 createCXTUResourceUsageEntry(*entries,
6758 CXTUResourceUsage_SourceManagerContentCache,
6759 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6760
6761 // How much memory is being used by the MemoryBuffer's in SourceManager?
6762 const SourceManager::MemoryBufferSizes &srcBufs =
6763 astUnit->getSourceManager().getMemoryBufferSizes();
6764
6765 createCXTUResourceUsageEntry(*entries,
6766 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6767 (unsigned long) srcBufs.malloc_bytes);
6768 createCXTUResourceUsageEntry(*entries,
6769 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6770 (unsigned long) srcBufs.mmap_bytes);
6771 createCXTUResourceUsageEntry(*entries,
6772 CXTUResourceUsage_SourceManager_DataStructures,
6773 (unsigned long) astContext.getSourceManager()
6774 .getDataStructureSizes());
6775
6776 // How much memory is being used by the ExternalASTSource?
6777 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6778 const ExternalASTSource::MemoryBufferSizes &sizes =
6779 esrc->getMemoryBufferSizes();
6780
6781 createCXTUResourceUsageEntry(*entries,
6782 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6783 (unsigned long) sizes.malloc_bytes);
6784 createCXTUResourceUsageEntry(*entries,
6785 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6786 (unsigned long) sizes.mmap_bytes);
6787 }
6788
6789 // How much memory is being used by the Preprocessor?
6790 Preprocessor &pp = astUnit->getPreprocessor();
6791 createCXTUResourceUsageEntry(*entries,
6792 CXTUResourceUsage_Preprocessor,
6793 pp.getTotalMemory());
6794
6795 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6796 createCXTUResourceUsageEntry(*entries,
6797 CXTUResourceUsage_PreprocessingRecord,
6798 pRec->getTotalMemory());
6799 }
6800
6801 createCXTUResourceUsageEntry(*entries,
6802 CXTUResourceUsage_Preprocessor_HeaderSearch,
6803 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006804
Guy Benyei11169dd2012-12-18 14:30:41 +00006805 CXTUResourceUsage usage = { (void*) entries.get(),
6806 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006807 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006808 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006809 return usage;
6810}
6811
6812void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6813 if (usage.data)
6814 delete (MemUsageEntries*) usage.data;
6815}
6816
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006817CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6818 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006819 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006820 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006821
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006822 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006823 LOG_BAD_TU(TU);
6824 return skipped;
6825 }
6826
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006827 if (!file)
6828 return skipped;
6829
6830 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6831 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6832 if (!ppRec)
6833 return skipped;
6834
6835 ASTContext &Ctx = astUnit->getASTContext();
6836 SourceManager &sm = Ctx.getSourceManager();
6837 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6838 FileID wantedFileID = sm.translateFile(fileEntry);
6839
6840 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6841 std::vector<SourceRange> wantedRanges;
6842 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6843 i != ei; ++i) {
6844 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6845 wantedRanges.push_back(*i);
6846 }
6847
6848 skipped->count = wantedRanges.size();
6849 skipped->ranges = new CXSourceRange[skipped->count];
6850 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6851 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6852
6853 return skipped;
6854}
6855
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006856void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6857 if (ranges) {
6858 delete[] ranges->ranges;
6859 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006860 }
6861}
6862
Guy Benyei11169dd2012-12-18 14:30:41 +00006863} // end extern "C"
6864
6865void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6866 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6867 for (unsigned I = 0; I != Usage.numEntries; ++I)
6868 fprintf(stderr, " %s: %lu\n",
6869 clang_getTUResourceUsageName(Usage.entries[I].kind),
6870 Usage.entries[I].amount);
6871
6872 clang_disposeCXTUResourceUsage(Usage);
6873}
6874
6875//===----------------------------------------------------------------------===//
6876// Misc. utility functions.
6877//===----------------------------------------------------------------------===//
6878
6879/// Default to using an 8 MB stack size on "safety" threads.
6880static unsigned SafetyStackThreadSize = 8 << 20;
6881
6882namespace clang {
6883
6884bool RunSafely(llvm::CrashRecoveryContext &CRC,
6885 void (*Fn)(void*), void *UserData,
6886 unsigned Size) {
6887 if (!Size)
6888 Size = GetSafetyThreadStackSize();
6889 if (Size)
6890 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6891 return CRC.RunSafely(Fn, UserData);
6892}
6893
6894unsigned GetSafetyThreadStackSize() {
6895 return SafetyStackThreadSize;
6896}
6897
6898void SetSafetyThreadStackSize(unsigned Value) {
6899 SafetyStackThreadSize = Value;
6900}
6901
6902}
6903
6904void clang::setThreadBackgroundPriority() {
6905 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6906 return;
6907
Alp Toker1a86ad22014-07-06 06:24:00 +00006908#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006909 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6910#endif
6911}
6912
6913void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6914 if (!Unit)
6915 return;
6916
6917 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6918 DEnd = Unit->stored_diag_end();
6919 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006920 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006921 CXString Msg = clang_formatDiagnostic(&Diag,
6922 clang_defaultDiagnosticDisplayOptions());
6923 fprintf(stderr, "%s\n", clang_getCString(Msg));
6924 clang_disposeString(Msg);
6925 }
6926#ifdef LLVM_ON_WIN32
6927 // On Windows, force a flush, since there may be multiple copies of
6928 // stderr and stdout in the file system, all with different buffers
6929 // but writing to the same device.
6930 fflush(stderr);
6931#endif
6932}
6933
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006934MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6935 SourceLocation MacroDefLoc,
6936 CXTranslationUnit TU){
6937 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006938 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006939 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006940 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006941
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006942 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006943 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006944 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006945 if (MD) {
6946 for (MacroDirective::DefInfo
6947 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6948 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6949 return Def.getMacroInfo();
6950 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006951 }
6952
Craig Topper69186e72014-06-08 08:38:04 +00006953 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006954}
6955
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006956const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6957 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006958 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006959 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006960 const IdentifierInfo *II = MacroDef->getName();
6961 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006962 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006963
6964 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6965}
6966
6967MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6968 const Token &Tok,
6969 CXTranslationUnit TU) {
6970 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006971 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006972 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006973 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006974
6975 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006976 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006977 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6978 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006979 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006980
6981 // Check that the token is inside the definition and not its argument list.
6982 SourceManager &SM = Unit->getSourceManager();
6983 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006984 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006985 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006986 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006987
6988 Preprocessor &PP = Unit->getPreprocessor();
6989 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6990 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006991 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006992
Alp Toker2d57cea2014-05-17 04:53:25 +00006993 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006994 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006995 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006996
6997 // Check that the identifier is not one of the macro arguments.
6998 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007001 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7002 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007003 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007004
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007005 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007006}
7007
7008MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7009 SourceLocation Loc,
7010 CXTranslationUnit TU) {
7011 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007012 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007013
7014 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007015 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007016 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007017 Preprocessor &PP = Unit->getPreprocessor();
7018 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007019 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007020 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7021 Token Tok;
7022 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007023 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007024
7025 return checkForMacroInMacroDefinition(MI, Tok, TU);
7026}
7027
Guy Benyei11169dd2012-12-18 14:30:41 +00007028extern "C" {
7029
7030CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007031 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007032}
7033
7034} // end: extern "C"
7035
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007036Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7037 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007038 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007039 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007040 if (Unit->isMainFileAST())
7041 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007042 return *this;
7043 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007044 } else {
7045 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007046 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007047 return *this;
7048}
7049
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007050Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7051 *this << FE->getName();
7052 return *this;
7053}
7054
7055Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7056 CXString cursorName = clang_getCursorDisplayName(cursor);
7057 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7058 clang_disposeString(cursorName);
7059 return *this;
7060}
7061
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007062Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7063 CXFile File;
7064 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007065 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007066 CXString FileName = clang_getFileName(File);
7067 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7068 clang_disposeString(FileName);
7069 return *this;
7070}
7071
7072Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7073 CXSourceLocation BLoc = clang_getRangeStart(range);
7074 CXSourceLocation ELoc = clang_getRangeEnd(range);
7075
7076 CXFile BFile;
7077 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007078 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007079
7080 CXFile EFile;
7081 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007082 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007083
7084 CXString BFileName = clang_getFileName(BFile);
7085 if (BFile == EFile) {
7086 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7087 BLine, BColumn, ELine, EColumn);
7088 } else {
7089 CXString EFileName = clang_getFileName(EFile);
7090 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7091 BLine, BColumn)
7092 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7093 ELine, EColumn);
7094 clang_disposeString(EFileName);
7095 }
7096 clang_disposeString(BFileName);
7097 return *this;
7098}
7099
7100Logger &cxindex::Logger::operator<<(CXString Str) {
7101 *this << clang_getCString(Str);
7102 return *this;
7103}
7104
7105Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7106 LogOS << Fmt;
7107 return *this;
7108}
7109
Chandler Carruth37ad2582014-06-27 15:14:39 +00007110static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7111
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007112cxindex::Logger::~Logger() {
7113 LogOS.flush();
7114
Chandler Carruth37ad2582014-06-27 15:14:39 +00007115 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007116
7117 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7118
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007119 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007120 OS << "[libclang:" << Name << ':';
7121
Alp Toker1a86ad22014-07-06 06:24:00 +00007122#ifdef USE_DARWIN_THREADS
7123 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007124 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7125 OS << tid << ':';
7126#endif
7127
7128 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7129 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7130 OS << Msg.str() << '\n';
7131
7132 if (Trace) {
7133 llvm::sys::PrintStackTrace(stderr);
7134 OS << "--------------------------------------------------\n";
7135 }
7136}